mirror of
https://github.com/grafana/grafana.git
synced 2026-01-07 22:41:10 +08:00
Compare commits
10 Commits
v8.0.x
...
v5.3.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69b4bf8125 | ||
|
|
62f85c3772 | ||
|
|
2e0165e80a | ||
|
|
272840e0cb | ||
|
|
694c738b6d | ||
|
|
a493a773a2 | ||
|
|
c6f7ae4e02 | ||
|
|
a049b22cb0 | ||
|
|
c026e6f320 | ||
|
|
e05033a693 |
12
.bra.toml
12
.bra.toml
@@ -1,19 +1,17 @@
|
||||
[run]
|
||||
init_cmds = [
|
||||
["go", "run", "build.go", "-dev", "build-cli"],
|
||||
["go", "run", "build.go", "-dev", "build-server"],
|
||||
["./bin/grafana-server", "-packaging=dev", "cfg:app_mode=development"]
|
||||
["./bin/grafana-server", "cfg:app_mode=development"]
|
||||
]
|
||||
watch_all = true
|
||||
follow_symlinks = true
|
||||
watch_dirs = [
|
||||
"$WORKDIR/pkg",
|
||||
"$WORKDIR/public/views",
|
||||
"$WORKDIR/conf",
|
||||
"$WORKDIR/pkg",
|
||||
"$WORKDIR/public/views",
|
||||
"$WORKDIR/conf",
|
||||
]
|
||||
watch_exts = [".go", ".ini", ".toml", ".template.html"]
|
||||
build_delay = 1500
|
||||
cmds = [
|
||||
["go", "run", "build.go", "-dev", "build-server"],
|
||||
["./bin/grafana-server", "-packaging=dev", "cfg:app_mode=development"]
|
||||
["./bin/grafana-server", "cfg:app_mode=development"]
|
||||
]
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
[dev]
|
||||
last 1 chrome versions
|
||||
last 1 firefox versions
|
||||
last 1 safari versions
|
||||
|
||||
[production]
|
||||
last 2 Firefox versions
|
||||
last 2 Chrome versions
|
||||
last 2 Safari versions
|
||||
last 2 Edge versions
|
||||
last 1 ios_saf versions
|
||||
last 1 and_chr versions
|
||||
last 1 samsung versions
|
||||
|
||||
|
||||
@@ -1,11 +1,423 @@
|
||||
version: 2.1
|
||||
aliases:
|
||||
# Workflow filters
|
||||
- &filter-only-release
|
||||
branches:
|
||||
ignore: /.*/
|
||||
tags:
|
||||
only: /^v[0-9]+(\.[0-9]+){2}(-.+|[^-.]*)$/
|
||||
- &filter-not-release-or-master
|
||||
tags:
|
||||
ignore: /^v[0-9]+(\.[0-9]+){2}(-.+|[^-.]*)$/
|
||||
branches:
|
||||
ignore: master
|
||||
- &filter-only-master
|
||||
branches:
|
||||
only: master
|
||||
|
||||
version: 2
|
||||
|
||||
jobs:
|
||||
mysql-integration-test:
|
||||
docker:
|
||||
- image: circleci/golang:1.11
|
||||
- image: circleci/mysql:5.6-ram
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: rootpass
|
||||
MYSQL_DATABASE: grafana_tests
|
||||
MYSQL_USER: grafana
|
||||
MYSQL_PASSWORD: password
|
||||
working_directory: /go/src/github.com/grafana/grafana
|
||||
steps:
|
||||
- checkout
|
||||
- run: sudo apt update
|
||||
- run: sudo apt install -y mysql-client
|
||||
- run: dockerize -wait tcp://127.0.0.1:3306 -timeout 120s
|
||||
- run: cat devenv/docker/blocks/mysql_tests/setup.sql | mysql -h 127.0.0.1 -P 3306 -u root -prootpass
|
||||
- run:
|
||||
name: mysql integration tests
|
||||
command: 'GRAFANA_TEST_DB=mysql go test ./pkg/services/sqlstore/... ./pkg/tsdb/mysql/... '
|
||||
|
||||
postgres-integration-test:
|
||||
docker:
|
||||
- image: circleci/golang:1.11
|
||||
- image: circleci/postgres:9.3-ram
|
||||
environment:
|
||||
POSTGRES_USER: grafanatest
|
||||
POSTGRES_PASSWORD: grafanatest
|
||||
POSTGRES_DB: grafanatest
|
||||
working_directory: /go/src/github.com/grafana/grafana
|
||||
steps:
|
||||
- checkout
|
||||
- run: sudo apt update
|
||||
- run: sudo apt install -y postgresql-client
|
||||
- run: dockerize -wait tcp://127.0.0.1:5432 -timeout 120s
|
||||
- run: 'PGPASSWORD=grafanatest psql -p 5432 -h 127.0.0.1 -U grafanatest -d grafanatest -f devenv/docker/blocks/postgres_tests/setup.sql'
|
||||
- run:
|
||||
name: postgres integration tests
|
||||
command: 'GRAFANA_TEST_DB=postgres go test ./pkg/services/sqlstore/... ./pkg/tsdb/postgres/...'
|
||||
|
||||
codespell:
|
||||
docker:
|
||||
- image: circleci/python
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: install codespell
|
||||
command: 'sudo pip install codespell'
|
||||
- run:
|
||||
# Important: all words have to be in lowercase, and separated by "\n".
|
||||
name: exclude known exceptions
|
||||
command: 'echo -e "unknwon" > words_to_ignore.txt'
|
||||
- run:
|
||||
name: check documentation spelling errors
|
||||
command: 'codespell -I ./words_to_ignore.txt docs/'
|
||||
|
||||
gometalinter:
|
||||
docker:
|
||||
- image: circleci/golang:1.11
|
||||
environment:
|
||||
# we need CGO because of go-sqlite3
|
||||
CGO_ENABLED: 1
|
||||
working_directory: /go/src/github.com/grafana/grafana
|
||||
steps:
|
||||
- checkout
|
||||
- run: 'go get -u github.com/alecthomas/gometalinter'
|
||||
- run: 'go get -u github.com/tsenart/deadcode'
|
||||
- run: 'go get -u github.com/jgautheron/goconst/cmd/goconst'
|
||||
- run: 'go get -u github.com/gordonklaus/ineffassign'
|
||||
- run: 'go get -u github.com/opennota/check/cmd/structcheck'
|
||||
- run: 'go get -u github.com/mdempsky/unconvert'
|
||||
- run: 'go get -u github.com/opennota/check/cmd/varcheck'
|
||||
- run:
|
||||
name: run linters
|
||||
command: 'gometalinter --enable-gc --vendor --deadline 10m --disable-all --enable=deadcode --enable=goconst --enable=ineffassign --enable=structcheck --enable=unconvert --enable=varcheck ./...'
|
||||
- run:
|
||||
name: run go vet
|
||||
command: 'go vet ./pkg/...'
|
||||
|
||||
test-frontend:
|
||||
docker:
|
||||
- image: circleci/node:8
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
key: dependency-cache-{{ checksum "yarn.lock" }}
|
||||
- run:
|
||||
name: yarn install
|
||||
command: 'yarn install --pure-lockfile --no-progress'
|
||||
no_output_timeout: 15m
|
||||
- save_cache:
|
||||
key: dependency-cache-{{ checksum "yarn.lock" }}
|
||||
paths:
|
||||
- node_modules
|
||||
- run:
|
||||
name: frontend tests
|
||||
command: './scripts/circle-test-frontend.sh'
|
||||
|
||||
test-backend:
|
||||
docker:
|
||||
- image: circleci/golang:1.11
|
||||
working_directory: /go/src/github.com/grafana/grafana
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: build backend and run go tests
|
||||
command: './scripts/circle-test-backend.sh'
|
||||
|
||||
build-all:
|
||||
docker:
|
||||
- image: grafana/build-container:1.1.0
|
||||
working_directory: /go/src/github.com/grafana/grafana
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: prepare build tools
|
||||
command: '/tmp/bootstrap.sh'
|
||||
- restore_cache:
|
||||
key: phantomjs-binaries-{{ checksum "scripts/build/download-phantomjs.sh" }}
|
||||
- run:
|
||||
name: download phantomjs binaries
|
||||
command: './scripts/build/download-phantomjs.sh'
|
||||
- save_cache:
|
||||
key: phantomjs-binaries-{{ checksum "scripts/build/download-phantomjs.sh" }}
|
||||
paths:
|
||||
- /tmp/phantomjs
|
||||
- run:
|
||||
name: build and package grafana
|
||||
command: './scripts/build/build-all.sh'
|
||||
- run:
|
||||
name: sign packages
|
||||
command: './scripts/build/sign_packages.sh'
|
||||
- run:
|
||||
name: verify signed packages
|
||||
command: |
|
||||
mkdir -p ~/.rpmdb/pubkeys
|
||||
curl -s https://grafanarel.s3.amazonaws.com/RPM-GPG-KEY-grafana > ~/.rpmdb/pubkeys/grafana.key
|
||||
./scripts/build/verify_signed_packages.sh dist/*.rpm
|
||||
- run:
|
||||
name: sha-sum packages
|
||||
command: 'go run build.go sha-dist'
|
||||
- run:
|
||||
name: Build Grafana.com master publisher
|
||||
command: 'go build -o scripts/publish scripts/build/publish.go'
|
||||
- run:
|
||||
name: Build Grafana.com release publisher
|
||||
command: 'cd scripts/build/release_publisher && go build -o release_publisher .'
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
- dist/grafana*
|
||||
- scripts/*.sh
|
||||
- scripts/publish
|
||||
- scripts/build/release_publisher/release_publisher
|
||||
|
||||
build:
|
||||
docker:
|
||||
- image: alpine:3.7
|
||||
- image: grafana/build-container:1.1.0
|
||||
working_directory: /go/src/github.com/grafana/grafana
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: The First Step
|
||||
command: |
|
||||
echo 'Fake step!'
|
||||
name: prepare build tools
|
||||
command: '/tmp/bootstrap.sh'
|
||||
- run:
|
||||
name: build and package grafana
|
||||
command: './scripts/build/build.sh'
|
||||
- run:
|
||||
name: sign packages
|
||||
command: './scripts/build/sign_packages.sh'
|
||||
- run:
|
||||
name: sha-sum packages
|
||||
command: 'go run build.go sha-dist'
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
- dist/grafana*
|
||||
|
||||
grafana-docker-master:
|
||||
docker:
|
||||
- image: docker:stable-git
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- setup_remote_docker
|
||||
- run: docker info
|
||||
- run: cp dist/grafana-latest.linux-x64.tar.gz packaging/docker
|
||||
- run: cd packaging/docker && ./build-deploy.sh "master-${CIRCLE_SHA1}"
|
||||
|
||||
grafana-docker-pr:
|
||||
docker:
|
||||
- image: docker:stable-git
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- setup_remote_docker
|
||||
- run: docker info
|
||||
- run: cp dist/grafana-latest.linux-x64.tar.gz packaging/docker
|
||||
- run: cd packaging/docker && ./build.sh "${CIRCLE_SHA1}"
|
||||
|
||||
grafana-docker-release:
|
||||
docker:
|
||||
- image: docker:stable-git
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- setup_remote_docker
|
||||
- run: docker info
|
||||
- run: cp dist/grafana-latest.linux-x64.tar.gz packaging/docker
|
||||
- run: cd packaging/docker && ./build-deploy.sh "${CIRCLE_TAG}"
|
||||
|
||||
build-enterprise:
|
||||
docker:
|
||||
- image: grafana/build-container:v0.1
|
||||
working_directory: /go/src/github.com/grafana/grafana
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: build, test and package grafana enterprise
|
||||
command: './scripts/build/build_enterprise.sh'
|
||||
- run:
|
||||
name: sign packages
|
||||
command: './scripts/build/sign_packages.sh'
|
||||
- run:
|
||||
name: sha-sum packages
|
||||
command: 'go run build.go sha-dist'
|
||||
- run:
|
||||
name: move enterprise packages into their own folder
|
||||
command: 'mv dist enterprise-dist'
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
- enterprise-dist/grafana-enterprise*
|
||||
|
||||
deploy-enterprise-master:
|
||||
docker:
|
||||
- image: circleci/python:2.7-stretch
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
name: install awscli
|
||||
command: 'sudo pip install awscli'
|
||||
- run:
|
||||
name: deploy to s3
|
||||
command: 'aws s3 sync ./enterprise-dist s3://$ENTERPRISE_BUCKET_NAME/master'
|
||||
|
||||
deploy-master:
|
||||
docker:
|
||||
- image: circleci/python:2.7-stretch
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
name: install awscli
|
||||
command: 'sudo pip install awscli'
|
||||
- run:
|
||||
name: deploy to s3
|
||||
command: |
|
||||
# Also
|
||||
cp dist/grafana-latest.linux-x64.tar.gz dist/grafana-master-$(echo "${CIRCLE_SHA1}" | cut -b1-7).linux-x64.tar.gz
|
||||
aws s3 sync ./dist s3://$BUCKET_NAME/master
|
||||
- run:
|
||||
name: Trigger Windows build
|
||||
command: './scripts/trigger_windows_build.sh ${APPVEYOR_TOKEN} ${CIRCLE_SHA1} master'
|
||||
- run:
|
||||
name: Publish to Grafana.com
|
||||
command: |
|
||||
rm dist/grafana-master-$(echo "${CIRCLE_SHA1}" | cut -b1-7).linux-x64.tar.gz
|
||||
./scripts/publish -apiKey ${GRAFANA_COM_API_KEY}
|
||||
|
||||
deploy-release:
|
||||
docker:
|
||||
- image: circleci/python:2.7-stretch
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
name: install awscli
|
||||
command: 'sudo pip install awscli'
|
||||
- run:
|
||||
name: deploy to s3
|
||||
command: 'aws s3 sync ./dist s3://$BUCKET_NAME/release'
|
||||
- run:
|
||||
name: Deploy to Grafana.com
|
||||
command: './scripts/build/publish.sh'
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
build-master:
|
||||
jobs:
|
||||
- build-all:
|
||||
filters: *filter-only-master
|
||||
- build-enterprise:
|
||||
filters: *filter-only-master
|
||||
- codespell:
|
||||
filters: *filter-only-master
|
||||
- gometalinter:
|
||||
filters: *filter-only-master
|
||||
- test-frontend:
|
||||
filters: *filter-only-master
|
||||
- test-backend:
|
||||
filters: *filter-only-master
|
||||
- mysql-integration-test:
|
||||
filters: *filter-only-master
|
||||
- postgres-integration-test:
|
||||
filters: *filter-only-master
|
||||
- deploy-master:
|
||||
requires:
|
||||
- build-all
|
||||
- test-backend
|
||||
- test-frontend
|
||||
- codespell
|
||||
- gometalinter
|
||||
- mysql-integration-test
|
||||
- postgres-integration-test
|
||||
filters: *filter-only-master
|
||||
- grafana-docker-master:
|
||||
requires:
|
||||
- build-all
|
||||
- test-backend
|
||||
- test-frontend
|
||||
- codespell
|
||||
- gometalinter
|
||||
- mysql-integration-test
|
||||
- postgres-integration-test
|
||||
filters: *filter-only-master
|
||||
- deploy-enterprise-master:
|
||||
requires:
|
||||
- build-all
|
||||
- test-backend
|
||||
- test-frontend
|
||||
- codespell
|
||||
- gometalinter
|
||||
- mysql-integration-test
|
||||
- postgres-integration-test
|
||||
- build-enterprise
|
||||
filters: *filter-only-master
|
||||
|
||||
release:
|
||||
jobs:
|
||||
- build-all:
|
||||
filters: *filter-only-release
|
||||
- codespell:
|
||||
filters: *filter-only-release
|
||||
- gometalinter:
|
||||
filters: *filter-only-release
|
||||
- test-frontend:
|
||||
filters: *filter-only-release
|
||||
- test-backend:
|
||||
filters: *filter-only-release
|
||||
- mysql-integration-test:
|
||||
filters: *filter-only-release
|
||||
- postgres-integration-test:
|
||||
filters: *filter-only-release
|
||||
- deploy-release:
|
||||
requires:
|
||||
- build-all
|
||||
- test-backend
|
||||
- test-frontend
|
||||
- codespell
|
||||
- gometalinter
|
||||
- mysql-integration-test
|
||||
- postgres-integration-test
|
||||
filters: *filter-only-release
|
||||
- grafana-docker-release:
|
||||
requires:
|
||||
- build-all
|
||||
- test-backend
|
||||
- test-frontend
|
||||
- codespell
|
||||
- gometalinter
|
||||
- mysql-integration-test
|
||||
- postgres-integration-test
|
||||
filters: *filter-only-release
|
||||
|
||||
build-branches-and-prs:
|
||||
jobs:
|
||||
- build:
|
||||
filters: *filter-not-release-or-master
|
||||
- codespell:
|
||||
filters: *filter-not-release-or-master
|
||||
- gometalinter:
|
||||
filters: *filter-not-release-or-master
|
||||
- test-frontend:
|
||||
filters: *filter-not-release-or-master
|
||||
- test-backend:
|
||||
filters: *filter-not-release-or-master
|
||||
- mysql-integration-test:
|
||||
filters: *filter-not-release-or-master
|
||||
- postgres-integration-test:
|
||||
filters: *filter-not-release-or-master
|
||||
- grafana-docker-pr:
|
||||
requires:
|
||||
- build
|
||||
- test-backend
|
||||
- test-frontend
|
||||
- codespell
|
||||
- gometalinter
|
||||
- mysql-integration-test
|
||||
- postgres-integration-test
|
||||
filters: *filter-not-release-or-master
|
||||
|
||||
17
.drone.star
17
.drone.star
@@ -1,17 +0,0 @@
|
||||
# To generate the .drone.yml file:
|
||||
# 1. Modify the *.star definitions
|
||||
# 2. Login to drone and export the env variables (token and server) shown here: https://drone.grafana.net/account
|
||||
# 3. Run `make drone`
|
||||
# More information about this process here: https://github.com/grafana/deployment_tools/blob/master/docs/infrastructure/drone/signing.md
|
||||
|
||||
load('scripts/pr.star', 'pr_pipelines')
|
||||
load('scripts/main.star', 'main_pipelines')
|
||||
load('scripts/release.star', 'release_pipelines', 'test_release_pipelines')
|
||||
load('scripts/version.star', 'version_branch_pipelines')
|
||||
load('scripts/job.star', 'cronjobs')
|
||||
load('scripts/vault.star', 'secrets')
|
||||
|
||||
def main(ctx):
|
||||
edition = 'oss'
|
||||
return pr_pipelines(edition=edition) + main_pipelines(edition=edition) + release_pipelines() + \
|
||||
test_release_pipelines() + version_branch_pipelines() + cronjobs(edition=edition) + secrets()
|
||||
3493
.drone.yml
3493
.drone.yml
File diff suppressed because it is too large
Load Diff
@@ -16,15 +16,5 @@ charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{js,ts,tsx,scss}]
|
||||
quote_type = single
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
indent_size = 2
|
||||
|
||||
[*.star]
|
||||
indent_size = 4
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
node_modules
|
||||
compiled
|
||||
build
|
||||
vendor
|
||||
devenv
|
||||
data
|
||||
dist
|
||||
e2e/tmp
|
||||
28
.eslintrc
28
.eslintrc
@@ -1,28 +0,0 @@
|
||||
{
|
||||
"extends": ["@grafana/eslint-config"],
|
||||
"root": true,
|
||||
"plugins": ["no-only-tests", "@emotion", "lodash"],
|
||||
"rules": {
|
||||
"no-only-tests/no-only-tests": "error",
|
||||
"react/prop-types": "off",
|
||||
"@emotion/jsx-import": "error",
|
||||
"lodash/import-scope": [2, "member"]
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["packages/grafana-ui/src/components/uPlot/**/*.{ts,tsx}"],
|
||||
"rules": {
|
||||
"react-hooks/rules-of-hooks": "off",
|
||||
"react-hooks/exhaustive-deps": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["packages/grafana-ui/src/components/ThemeDemos/**/*.{ts,tsx}"],
|
||||
"rules": {
|
||||
"@emotion/jsx-import": "off",
|
||||
"react/jsx-uses-react": "off",
|
||||
"react/react-in-jsx-scope": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1 +0,0 @@
|
||||
* text=auto eol=lf
|
||||
93
.github/CODEOWNERS
vendored
93
.github/CODEOWNERS
vendored
@@ -1,93 +0,0 @@
|
||||
# Lines starting with '#' are comments.
|
||||
# Each line is a file pattern followed by one or more owners.
|
||||
|
||||
# More details are here: https://help.github.com/articles/about-codeowners/
|
||||
|
||||
# The '*' pattern is global owners.
|
||||
|
||||
# Order is important. The last matching pattern has the most precedence.
|
||||
# The folders are ordered as follows:
|
||||
|
||||
# In each subsection folders are ordered first by depth, then alphabetically.
|
||||
# This should make it easy to add new rules without breaking existing ones.
|
||||
|
||||
# Documentation owner: Diana Payton
|
||||
/docs/ @grafana/docs-squad
|
||||
/contribute/ @marcusolsson @grafana/docs-squad
|
||||
/docs/sources/developers/plugins/ @marcusolsson @grafana/docs-squad
|
||||
/docs/sources/enterprise/ @osg-grafana @grafana/docs-squad
|
||||
|
||||
# Backend code
|
||||
*.go @grafana/backend-platform
|
||||
go.mod @grafana/backend-platform
|
||||
go.sum @grafana/backend-platform
|
||||
|
||||
# Cloud Datasources backend code
|
||||
/pkg/tsdb/cloudwatch @grafana/cloud-datasources @grafana/observability-squad
|
||||
/pkg/tsdb/azuremonitor @grafana/cloud-datasources
|
||||
/pkg/tsdb/cloudmonitoring @grafana/cloud-datasources
|
||||
|
||||
# Observability backend code
|
||||
/pkg/tsdb/influxdb @grafana/observability-squad
|
||||
/pkg/tsdb/elasticsearch @grafana/observability-squad
|
||||
/pkg/tsdb/graphite @grafana/observability-squad
|
||||
/pkg/tsdb/jaeger @grafana/observability-squad
|
||||
/pkg/tsdb/loki @grafana/observability-squad
|
||||
/pkg/tsdb/zipkin @grafana/observability-squad
|
||||
/pkg/tsdb/tempo @grafana/observability-squad
|
||||
|
||||
# Unified Alerting
|
||||
/pkg/services/ngalert @grafana/alerting-squad
|
||||
/pkg/services/sqlstore/migrations/ualert @grafana/alerting-squad
|
||||
|
||||
# Database migrations
|
||||
/pkg/services/sqlstore/migrations @grafana/backend-platform @grafana/hosted-grafana-team
|
||||
*_mig.go @grafana/backend-platform @grafana/hosted-grafana-team
|
||||
|
||||
# Backend code docs
|
||||
/contribute/style-guides/backend.md @grafana/backend-platform
|
||||
/contribute/architecture/backend @grafana/backend-platform
|
||||
/contribute/engineering/backend @grafana/backend-platform
|
||||
|
||||
/e2e @grafana/grafana-frontend-platform
|
||||
/packages @grafana/grafana-frontend-platform
|
||||
/plugins-bundled @grafana/grafana-frontend-platform
|
||||
/public @grafana/grafana-frontend-platform
|
||||
/scripts/build/release-packages.sh @grafana/grafana-frontend-platform
|
||||
/scripts/circle-release-next-packages.sh @grafana/grafana-frontend-platform
|
||||
/scripts/ci-frontend-metrics.sh @grafana/grafana-frontend-platform
|
||||
/scripts/grunt @grafana/grafana-frontend-platform
|
||||
/scripts/webpack @grafana/grafana-frontend-platform
|
||||
package.json @grafana/grafana-frontend-platform
|
||||
tsconfig.json @grafana/grafana-frontend-platform
|
||||
lerna.json @grafana/grafana-frontend-platform
|
||||
.babelrc @grafana/grafana-frontend-platform
|
||||
.prettierrc.js @grafana/grafana-frontend-platform
|
||||
.eslintrc @grafana/grafana-frontend-platform
|
||||
|
||||
# @grafana/ui component documentation
|
||||
*.mdx @marcusolsson @jessover9000 @grafana/grafana-frontend-platform
|
||||
|
||||
/public/app/features/explore/ @grafana/observability-squad
|
||||
/packages/jaeger-ui-components/ @grafana/observability-squad
|
||||
|
||||
# Core datasources
|
||||
/public/app/plugins/datasource/cloudwatch @grafana/cloud-datasources @grafana/observability-squad
|
||||
/public/app/plugins/datasource/elasticsearch @grafana/observability-squad
|
||||
/public/app/plugins/datasource/grafana-azure-monitor-datasource @grafana/cloud-datasources
|
||||
/public/app/plugins/datasource/graphite @grafana/observability-squad
|
||||
/public/app/plugins/datasource/influxdb @grafana/observability-squad
|
||||
/public/app/plugins/datasource/jaeger @grafana/observability-squad
|
||||
/public/app/plugins/datasource/loki @grafana/observability-squad
|
||||
/public/app/plugins/datasource/mssql @grafana/backend-platform
|
||||
/public/app/plugins/datasource/mysql @grafana/backend-platform
|
||||
/public/app/plugins/datasource/opentsdb @grafana/backend-platform
|
||||
/public/app/plugins/datasource/postgres @grafana/backend-platform
|
||||
/public/app/plugins/datasource/prometheus @grafana/observability-squad
|
||||
/public/app/plugins/datasource/cloud-monitoring @grafana/cloud-datasources
|
||||
/public/app/plugins/datasource/zipkin @grafana/observability-squad
|
||||
/public/app/plugins/datasource/tempo @grafana/observability-squad
|
||||
/public/app/plugins/datasource/alertmanager @grafana/alerting-squad
|
||||
|
||||
# Cloud middleware
|
||||
/grafana-mixin/ @grafana/cloud-middleware
|
||||
22
.github/CONTRIBUTING.md
vendored
Normal file
22
.github/CONTRIBUTING.md
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
Follow the setup guide in README.md
|
||||
|
||||
### Rebuild frontend assets on source change
|
||||
```
|
||||
yarn watch
|
||||
```
|
||||
|
||||
### Rerun tests on source change
|
||||
```
|
||||
yarn jest
|
||||
```
|
||||
|
||||
### Run tests for backend assets before commit
|
||||
```
|
||||
test -z "$(gofmt -s -l . | grep -v -E 'vendor/(github.com|golang.org|gopkg.in)' | tee /dev/stderr)"
|
||||
```
|
||||
|
||||
### Run tests for frontend assets before commit
|
||||
```
|
||||
yarn test
|
||||
go test -v ./pkg/...
|
||||
```
|
||||
16
.github/ISSUE_TEMPLATE.md
vendored
Normal file
16
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
Read before posting:
|
||||
|
||||
- Questions should be posted to https://community.grafana.com. Please search there and here on GitHub for similar issues before creating a new issue.
|
||||
- Checkout FAQ: https://community.grafana.com/c/howto/faq
|
||||
- Checkout How to troubleshoot metric query issues: https://community.grafana.com/t/how-to-troubleshoot-metric-query-issues/50
|
||||
|
||||
Please include this information:
|
||||
### What Grafana version are you using?
|
||||
### What datasource are you using?
|
||||
### What OS are you running grafana on?
|
||||
### What did you do?
|
||||
### What was the expected result?
|
||||
### What happened instead?
|
||||
### If related to metric query / data viz:
|
||||
### Include raw network request & response: get by opening Chrome Dev Tools (F12, Ctrl+Shift+I on windows, Cmd+Opt+I on Mac), go the network tab.
|
||||
|
||||
31
.github/ISSUE_TEMPLATE/1-bug_report.md
vendored
31
.github/ISSUE_TEMPLATE/1-bug_report.md
vendored
@@ -1,31 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Report a bug you found when using Grafana
|
||||
labels: 'type: bug'
|
||||
---
|
||||
|
||||
<!--
|
||||
Please use this template to create your bug report. By providing as much info as possible you help us understand the issue, reproduce it and resolve it for you quicker. Therefor take a couple of extra minutes to make sure you have provided all info needed.
|
||||
|
||||
PROTIP: record your screen and attach it as a gif to showcase the issue.
|
||||
|
||||
- Questions should be posted to: https://community.grafana.com
|
||||
- Use query inspector to troubleshoot issues: https://bit.ly/2XNF6YS
|
||||
- How to record and attach gif: https://bit.ly/2Mi8T6K
|
||||
-->
|
||||
|
||||
**What happened**:
|
||||
|
||||
**What you expected to happen**:
|
||||
|
||||
**How to reproduce it (as minimally and precisely as possible)**:
|
||||
|
||||
**Anything else we need to know?**:
|
||||
|
||||
**Environment**:
|
||||
- Grafana version:
|
||||
- Data source type & version:
|
||||
- OS Grafana is installed on:
|
||||
- User OS & Browser:
|
||||
- Grafana plugins:
|
||||
- Others:
|
||||
11
.github/ISSUE_TEMPLATE/2-feature_request.md
vendored
11
.github/ISSUE_TEMPLATE/2-feature_request.md
vendored
@@ -1,11 +0,0 @@
|
||||
---
|
||||
name: Enhancement request
|
||||
about: Suggest an enhancement or new feature for the Grafana project
|
||||
labels: 'type: feature request'
|
||||
---
|
||||
|
||||
<!-- Please only use this template for submitting feature requests -->
|
||||
|
||||
**What would you like to be added**:
|
||||
|
||||
**Why is this needed**:
|
||||
26
.github/ISSUE_TEMPLATE/3-accessibility.md
vendored
26
.github/ISSUE_TEMPLATE/3-accessibility.md
vendored
@@ -1,26 +0,0 @@
|
||||
---
|
||||
name: Accessibility issue
|
||||
about: Help make Grafana be better at keyboard navigation, screen-readable and accessible to all.
|
||||
labels: 'type: accessibility'
|
||||
---
|
||||
|
||||
<!--
|
||||
Please only use this template for submitting accessibility issues.
|
||||
|
||||
This is a new feature area for Grafana that we want to improve. We have long way to go
|
||||
to really improve accessibility and would like your help to know where to start.
|
||||
-->
|
||||
|
||||
**Steps to reproduce**:
|
||||
|
||||
**Actual Result**:
|
||||
|
||||
**Expected Result**
|
||||
|
||||
**Relevant WCAG Criteria:** [#.#.# WCAG Criterion](link to https://www.w3.org/WAI/WCAG21/quickref/?versions=2.0)
|
||||
|
||||
**Environment**:
|
||||
- Grafana version:
|
||||
- Data source type & version:
|
||||
- User OS & Browser:
|
||||
- Others:
|
||||
39
.github/ISSUE_TEMPLATE/4-grafana_ui_component.md
vendored
39
.github/ISSUE_TEMPLATE/4-grafana_ui_component.md
vendored
@@ -1,39 +0,0 @@
|
||||
---
|
||||
name: '@grafana/ui component request'
|
||||
about: Suggest a component for the @grafana/ui package
|
||||
labels: 'area/grafana/ui'
|
||||
---
|
||||
|
||||
<!--
|
||||
By using this template you will make it easier for us to make sure that documentation and implementation stays up to date for every component in @grafana/ui
|
||||
|
||||
Thank you!
|
||||
-->
|
||||
|
||||
**Why is this component needed**:
|
||||
<!-- Explain your use case -->
|
||||
___
|
||||
- [ ] Is/could it be used in more than one place in Grafana?
|
||||
|
||||
**Where is/could it be used?**:
|
||||
|
||||
___
|
||||
- [ ] Post screenshots possible.
|
||||
- [ ] It has a single use case.
|
||||
- [ ] It is/could be used in multiple places.
|
||||
|
||||
**Implementation** (Checklist meant for the person implementing the component)
|
||||
|
||||
- [ ] Component has a story in Storybook.
|
||||
- [ ] Props and naming follows [our style guide](https://github.com/grafana/grafana/blob/main/contribute/style-guides/frontend.md).
|
||||
- [ ] It is extendable (rest props are spread, styles with className work, and so on).
|
||||
- [ ] Uses [theme for spacing, colors, and so on](https://github.com/grafana/grafana/blob/main/contribute/style-guides/themes.md).
|
||||
- [ ] Works with both light and dark theme.
|
||||
|
||||
**Documentation**
|
||||
|
||||
- [ ] Properties are documented.
|
||||
- [ ] Use cases are described.
|
||||
- [ ] Code examples for the different use cases.
|
||||
- [ ] Dos and don'ts.
|
||||
- [ ] Styling guidelines, specific color usage (if applicable).
|
||||
5
.github/ISSUE_TEMPLATE/config.yml
vendored
5
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,5 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Questions & Help
|
||||
url: https://community.grafana.com
|
||||
about: Please ask and answer questions here.
|
||||
36
.github/PULL_REQUEST_TEMPLATE.md
vendored
36
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,34 +1,4 @@
|
||||
<!--
|
||||
|
||||
Thank you for sending a pull request! Here are some tips:
|
||||
|
||||
1. If this is your first time, please read our contribution guide at https://github.com/grafana/grafana/blob/main/CONTRIBUTING.md
|
||||
|
||||
2. Ensure you include and run the appropriate tests as part of your Pull Request.
|
||||
|
||||
3. In a new feature or configuration option, an update to the documentation is necessary. Everything related to the documentation is under the docs folder in the root of the repository.
|
||||
|
||||
4. If the Pull Request is a work in progress, make use of GitHub's "Draft PR" feature and mark it as such.
|
||||
|
||||
5. If you can not merge your Pull Request due to a merge conflict, Rebase it. This gets it in sync with the main branch.
|
||||
|
||||
6. Name your PR as "<FeatureArea>: Describe your change", e.g. Alerting: Prevent race condition. If it's a fix or feature relevant for the changelog describe the user impact in the title. The PR title is used to auto-generate the changelog for issues marked with the "add to changelog" label.
|
||||
|
||||
-->
|
||||
|
||||
**What this PR does / why we need it**:
|
||||
|
||||
**Which issue(s) this PR fixes**:
|
||||
|
||||
<!--
|
||||
|
||||
- Automatically closes linked issue when the Pull Request is merged.
|
||||
|
||||
Usage: "Fixes #<issue number>", or "Fixes (paste link of issue)"
|
||||
|
||||
-->
|
||||
|
||||
Fixes #
|
||||
|
||||
**Special notes for your reviewer**:
|
||||
* Link the PR to an issue for new features
|
||||
* Rebase your PR if it gets out of sync with master
|
||||
|
||||
**REMOVE THE TEXT ABOVE BEFORE CREATING THE PULL REQUEST**
|
||||
|
||||
30
.github/bot.md
vendored
30
.github/bot.md
vendored
@@ -1,30 +0,0 @@
|
||||
# GitHub & grafanabot automation
|
||||
|
||||
The bot is configured via [commands.json](https://github.com/grafana/grafana/blob/main/.github/commands.json) and some other GitHub workflows [workflows](https://github.com/grafana/grafana/tree/main/.github/workflows).
|
||||
|
||||
Comment commands:
|
||||
|
||||
* Write the word `/duplicate #<number>` anywhere in a comment and the bot will add the correct label and standard message.
|
||||
* Write the word `/needsMoreInfo` anywhere in a comment and the bot will add the correct label and standard message.
|
||||
|
||||
Label commands:
|
||||
|
||||
* Add label `bot/question` the the bot will close with standard question message and add label `type/question`
|
||||
* Add label `bot/duplicate` the the bot will close with standard duplicate message and add label `type/duplicate`
|
||||
* Add label `bot/needs more info` for bot to request more info (or use comment command mentioned above)
|
||||
* Add label `bot/close feature request` for bot to close a feature request with standard message and adds label `not implemented`
|
||||
* Add label `bot/no new info` for bot to close an issue where we asked for more info but has not received any updates in at least 14 days.
|
||||
|
||||
## Metrics
|
||||
|
||||
Metrics are configured in [metrics-collector.json](https://github.com/grafana/grafana/blob/main/.github/metrics-collector.json) and are also defined in the
|
||||
[metrics-collector](https://github.com/grafana/grafana-github-actions/blob/main/metrics-collector/index.ts) GitHub action.
|
||||
|
||||
## Backport PR
|
||||
|
||||
To automatically backport a PR to a release branch like v7.3.x add a label named `backport v7.3.x`. The label name should follow the pattern `backport <branch-name>`. Once merged grafanabot will automatically
|
||||
try to cherry-pick the PR merge commit into that branch and open a PR. It will sync the milestone with the source PR so make sure the source PR also is assigned the milestone for the patch release. If the PR is already merged you can still add this label and trigger the backport automation.
|
||||
|
||||
If there are merge conflicts the bot will write a comment on the source PR saying the cherry-pick failed. In this case you have to do the cherry pick and backport PR manually.
|
||||
|
||||
The backport logic is written [here](https://github.com/grafana/grafana-github-actions/blob/main/backport/backport.ts)
|
||||
53
.github/commands.json
vendored
53
.github/commands.json
vendored
@@ -1,53 +0,0 @@
|
||||
[
|
||||
{
|
||||
"type": "label",
|
||||
"name": "bot/question",
|
||||
"addLabel": "type/question",
|
||||
"removeLabel": "bot/question",
|
||||
"action": "close",
|
||||
"comment": "Please ask your question on [community.grafana.com/](https://community.grafana.com/). To avoid having your issue closed in the future, please read our [CONTRIBUTING](https://github.com/grafana/grafana/blob/main/CONTRIBUTING.md) guidelines.\n\nHappy graphing!"
|
||||
},
|
||||
{
|
||||
"type": "comment",
|
||||
"name": "duplicate",
|
||||
"allowUsers": [],
|
||||
"action": "updateLabels",
|
||||
"addLabel": "type/duplicate"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "bot/duplicate",
|
||||
"addLabel": "type/duplicate",
|
||||
"removeLabel": "bot/duplicate",
|
||||
"action": "close",
|
||||
"comment": "Thanks for creating this issue! It looks like this has already been reported by another user. We’ve closed this in favor of the existing one. Please consider adding any details you think is missing to that issue.\n\nTo avoid having your issue closed in the future, please read our [CONTRIBUTING](https://github.com/grafana/grafana/blob/main/CONTRIBUTING.md) guidelines.\n\nHappy graphing!"
|
||||
},
|
||||
{
|
||||
"type": "comment",
|
||||
"name": "needsMoreInfo",
|
||||
"allowUsers": [],
|
||||
"action": "updateLabels",
|
||||
"addLabel": "bot/needs more info"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "bot/needs more info",
|
||||
"action": "updateLabels",
|
||||
"addLabel": "needs more info",
|
||||
"removeLabel": "bot/needs more info",
|
||||
"comment": "Thanks for creating this issue! We think it's missing some basic information. \r\n\r\nFollow the issue template and add additional information that will help us replicate the problem. \r\nFor data visualization issues: \r\n- Query results from the inspect drawer (data tab & query inspector)\r\n- Panel settings can be extracted in the panel inspect drawer JSON tab\r\n\r\nFor dashboard related issues: \r\n- Dashboard JSON can be found in the dashboard settings JSON model view\r\n\r\nFor authentication, provisioning and alerting issues, Grafana server logs are useful. \r\n\r\nHappy graphing!"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "bot/no new info",
|
||||
"action": "close",
|
||||
"comment": "We've closed this issue since it needs more information and hasn't had any activity recently. We can re-open it after you you add more information. To avoid having your issue closed in the future, please read our [CONTRIBUTING](https://github.com/grafana/grafana/blob/main/CONTRIBUTING.md) guidelines.\n\nHappy graphing!"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "bot/close feature request",
|
||||
"action": "close",
|
||||
"addLabel": "not implemented",
|
||||
"comment": "This feature request has been open for a long time with few received upvotes or comments, so we are closing it. We're trying to limit open GitHub issues in order to better track planned work and features. \r\n\r\nThis doesn't mean that we'll never ever implement it or that we will never accept a PR for it. A closed issue can still attract upvotes and act as a ticket to track feature demand\/interest. \r\n\r\nThank You to you for taking the time to create this issue!"
|
||||
}
|
||||
]
|
||||
10
.github/dependabot.yml
vendored
10
.github/dependabot.yml
vendored
@@ -1,10 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
- package-ecosystem: "gomod"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
32
.github/metrics-collector.json
vendored
32
.github/metrics-collector.json
vendored
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"queries": [
|
||||
{
|
||||
"name": "type_bug",
|
||||
"query": "label:\"type/bug\" is:open"
|
||||
},
|
||||
{
|
||||
"name": "type_docs",
|
||||
"query": "label:\"type/docs\" is:open"
|
||||
},
|
||||
{
|
||||
"name": "needs_investigation",
|
||||
"query": "label:\"needs investigation\" is:open"
|
||||
},
|
||||
{
|
||||
"name": "needs_more_info",
|
||||
"query": "label:\"needs more info\" is:open"
|
||||
},
|
||||
{
|
||||
"name": "unlabeled",
|
||||
"query": "is:open is:issue no:label"
|
||||
},
|
||||
{
|
||||
"name": "open_prs",
|
||||
"query": "is:open is:pr"
|
||||
},
|
||||
{
|
||||
"name": "milestone_7_4_open",
|
||||
"query": "is:open is:issue milestone:7.4"
|
||||
}
|
||||
]
|
||||
}
|
||||
182
.github/pr-commands.json
vendored
182
.github/pr-commands.json
vendored
@@ -1,182 +0,0 @@
|
||||
[
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [
|
||||
"docs/**/*",
|
||||
"contribute/**/*"
|
||||
],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "type/docs"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [
|
||||
"public/**/*",
|
||||
"packages/**/*",
|
||||
"e2e/**/*",
|
||||
"plugins-bundled/**/*",
|
||||
"scripts/build/release-packages.sh",
|
||||
"scripts/circle-release-next-packages.sh",
|
||||
"scripts/ci-frontend-metrics.sh",
|
||||
"scripts/grunt/**/*",
|
||||
"scripts/webpack/**/*",
|
||||
"package.json",
|
||||
"tsconfig.json",
|
||||
"lerna.json",
|
||||
".babelrc",
|
||||
".prettierrc.js",
|
||||
".eslintrc",
|
||||
"**/*.mdx"
|
||||
],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "area/frontend"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [
|
||||
"**/*.go",
|
||||
"go.mod",
|
||||
"go.sum",
|
||||
"contribute/style-guides/backend.md",
|
||||
"contribute/architecture/backend/**/*",
|
||||
"scripts/go/**/*"
|
||||
],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "area/backend"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [
|
||||
"pkg/services/sqlstore/migrations/**/*",
|
||||
"**/*_mig.go"
|
||||
],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "area/backend/db/migration"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [ "public/app/features/explore/**/*"],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "area/explore"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [
|
||||
".circleci/**/*",
|
||||
"packaging/**/*",
|
||||
"scripts/build/**/*",
|
||||
"scripts/*.sh",
|
||||
"scripts/*.star",
|
||||
".drone.star",
|
||||
".drone.yml",
|
||||
"Makefile",
|
||||
"Dockerfile",
|
||||
"Dockerfile.ubuntu"
|
||||
],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "type/build-packaging"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [ "public/app/plugins/datasource/grafana-azure-monitor-datasource/**/*", "pkg/tsdb/azuremonitor/**/*"],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "datasource/Azure"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [ "public/app/plugins/datasource/cloud-monitoring/**/*", "pkg/tsdb/cloudmonitoring/**/*"],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "datasource/GoogleCloudMonitoring"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [ "public/app/plugins/datasource/cloudwatch/**/*", "pkg/tsdb/cloudwatch/**/*"],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "datasource/CloudWatch"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [ "public/app/plugins/datasource/elasticsearch/**/*", "pkg/tsdb/elasticsearch/**/*"],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "datasource/Elasticsearch"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [ "public/app/plugins/datasource/graphite/**/*", "pkg/tsdb/graphite/**/*"],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "datasource/Graphite"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [ "public/app/plugins/datasource/influxdb/**/*", "pkg/tsdb/influx/**/*"],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "datasource/InfluxDB"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [ "public/app/plugins/datasource/jaeger"],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "datasource/Jaeger"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [ "public/app/plugins/datasource/loki/**/*", "pkg/tsdb/loki/**/*"],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "datasource/Loki"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [ "public/app/plugins/datasource/mssql/**/*", "pkg/tsdb/mssql/**/*"],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "datasource/MSSQL"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [ "public/app/plugins/datasource/mysql/**/*", "pkg/tsdb/mysql/**/*"],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "datasource/MySQL"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [ "public/app/plugins/datasource/opentsdb/**/*", "pkg/tsdb/opentsdb/**/*"],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "datasource/OpenTSDB"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [ "public/app/plugins/datasource/postgres/**/*", "pkg/tsdb/postgres/**/*"],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "datasource/Postgres"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [ "public/app/plugins/datasource/prometheus/**/*", "pkg/tsdb/prometheus/**/*"],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "datasource/Prometheus"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [ "public/app/plugins/datasource/tempo/**/*", "pkg/tsdb/tempo/**/*"],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "datasource/Tempo"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [ "public/app/plugins/datasource/zipkin/**/*"],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "datasource/Zipkin"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": ["public/app/features/variables/**/*", "public/app/features/templating/**/*"],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "area/dashboard/templating"
|
||||
},
|
||||
{
|
||||
"type": "author",
|
||||
"name": "pr/external",
|
||||
"notMemberOf": { "org": "grafana" },
|
||||
"action": "updateLabel",
|
||||
"addLabel": "pr/external"
|
||||
}
|
||||
]
|
||||
47
.github/stale.yml
vendored
47
.github/stale.yml
vendored
@@ -1,47 +0,0 @@
|
||||
# Configuration for probot-stale - https://github.com/probot/stale
|
||||
|
||||
# General configuration
|
||||
# Label to use when marking as stale
|
||||
staleLabel: stale
|
||||
|
||||
# Pull request specific configuration
|
||||
pulls:
|
||||
# Number of days of inactivity before an Issue or Pull Request becomes stale
|
||||
daysUntilStale: 14
|
||||
# Number of days of inactivity before a stale Issue or Pull Request is closed.
|
||||
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
|
||||
daysUntilClose: 30
|
||||
# Comment to post when marking as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This pull request has been automatically marked as stale because it has not had
|
||||
activity in the last 2 weeks. It will be closed in 30 days if no further activity occurs. Please
|
||||
feel free to give a status update now, ping for review, or re-open when it's ready.
|
||||
Thank you for your contributions!
|
||||
# Comment to post when closing a stale Issue or Pull Request.
|
||||
closeComment: >
|
||||
This pull request has been automatically closed because it has not had
|
||||
activity in the last 30 days. Please feel free to give a status update now, ping for review, or re-open when it's ready.
|
||||
Thank you for your contributions!
|
||||
# Limit the number of actions per hour, from 1-30. Default is 30
|
||||
limitPerRun: 1
|
||||
|
||||
exemptLabels:
|
||||
- help wanted
|
||||
- type/bug
|
||||
- type/feature-request
|
||||
- Epic
|
||||
- no stalebot
|
||||
|
||||
# Issue specific configuration
|
||||
issues:
|
||||
limitPerRun: 1
|
||||
daysUntilStale: 100000
|
||||
daysUntilClose: 100000
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had activity in the
|
||||
last 100 days. It will be closed in the next 100 days if no activity occurs.
|
||||
Thank you for your contributions.
|
||||
closeComment: >
|
||||
This issue has been automatically closed because it has not had activity in the
|
||||
last month and a half. If this issue is still valid, please ping a maintainer and ask them to check this again.
|
||||
Thank you for your contributions.
|
||||
26
.github/workflows/backport.yml
vendored
26
.github/workflows/backport.yml
vendored
@@ -1,26 +0,0 @@
|
||||
name: Backport PR Creator
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- closed
|
||||
- labeled
|
||||
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Actions
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: "grafana/grafana-github-actions"
|
||||
path: ./actions
|
||||
ref: main
|
||||
- name: Install Actions
|
||||
run: npm install --production --prefix ./actions
|
||||
- name: Run backport
|
||||
uses: ./actions/backport
|
||||
with:
|
||||
metricsWriteAPIKey: ${{secrets.GRAFANA_MISC_STATS_API_KEY}}
|
||||
token: ${{secrets.GH_BOT_ACCESS_TOKEN}}
|
||||
labelsToAdd: "backport"
|
||||
title: "[{{base}}] {{originalTitle}}"
|
||||
65
.github/workflows/bump-version.yml
vendored
65
.github/workflows/bump-version.yml
vendored
@@ -1,65 +0,0 @@
|
||||
name: Bump version
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
required: true
|
||||
default: '7.x.x'
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# This is a basic workflow to help you get started with Actions
|
||||
- uses: actions-ecosystem/action-regex-match@v2
|
||||
id: regex-match
|
||||
with:
|
||||
text: ${{ github.event.inputs.version }}
|
||||
regex: '^(\d+.\d+).\d+(?:-beta.\d+)?$'
|
||||
|
||||
- name: Validate input version
|
||||
if: ${{ steps.regex-match.outputs.match == '' }}
|
||||
run: |
|
||||
echo "The input version format is not correct, please respect:\
|
||||
major.minor.patch or major.minor.patch-beta.number format. \
|
||||
example: 7.4.3 or 7.4.3-beta.1"
|
||||
exit 1
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set intermedia variables
|
||||
id: intermedia
|
||||
run: |
|
||||
echo "::set-output name=short_ref::${GITHUB_REF#refs/*/}"
|
||||
echo "::set-output name=check_passed::false"
|
||||
echo "::set-output name=branch_name::v${{steps.regex-match.outputs.group1}}"
|
||||
echo "::set-output name=branch_exist::$(git ls-remote --heads https://github.com/grafana/grafana.git v${{ steps.regex-match.outputs.group1 }}.x | wc -l)"
|
||||
|
||||
- name: Check input version is aligned with branch(not main)
|
||||
if: steps.intermedia.outputs.branch_exist != '0' && !contains(steps.intermedia.outputs.short_ref, steps.intermedia.outputs.branch_name)
|
||||
run: |
|
||||
echo " You need to run the workflow on branch v${{steps.regex-match.outputs.group1}}.x
|
||||
exit 1
|
||||
|
||||
- name: Check input version is aligned with branch(main)
|
||||
if: steps.intermedia.outputs.branch_exist == '0' && !contains(steps.intermedia.outputs.short_ref, 'main')
|
||||
run: |
|
||||
echo "When you want to deliver a new new minor version, you might want to create a new branch first \
|
||||
with naming convention v[major].[minor].x, and just run the workflow on that branch. \
|
||||
Run the workflow on main only when needed"
|
||||
exit 1
|
||||
|
||||
- name: Checkout Actions
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: "grafana/grafana-github-actions"
|
||||
path: ./actions
|
||||
ref: main
|
||||
- uses: actions/setup-node@v2.1.5
|
||||
with:
|
||||
node-version: '14'
|
||||
- name: Install Actions
|
||||
run: npm install --production --prefix ./actions
|
||||
- name: Run bump version
|
||||
uses: ./actions/bump-version
|
||||
with:
|
||||
token: ${{secrets.GH_BOT_ACCESS_TOKEN}}
|
||||
metricsWriteAPIKey: ${{secrets.GRAFANA_MISC_STATS_API_KEY}}
|
||||
66
.github/workflows/codeql-analysis.yml
vendored
66
.github/workflows/codeql-analysis.yml
vendored
@@ -1,66 +0,0 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, v1.8.x, v2.0.x, v2.1.x, v2.6.x, v3.0.x, v3.1.x, v4.0.x, v4.1.x, v4.2.x, v4.3.x, v4.4.x, v4.5.x, v4.6.x, v4.7.x, v5.0.x, v5.1.x, v5.2.x, v5.3.x, v5.4.x, v6.0.x, v6.1.x, v6.2.x, v6.3.x, v6.4.x, v6.5.x, v6.6.x, v6.7.x, v7.0.x, v7.1.x, v7.2.x]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [main]
|
||||
schedule:
|
||||
- cron: '0 4 * * 6'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Override automatic language detection by changing the below list
|
||||
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
|
||||
language: ['javascript', 'go', 'python']
|
||||
# Learn more...
|
||||
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
25
.github/workflows/commands.yml
vendored
25
.github/workflows/commands.yml
vendored
@@ -1,25 +0,0 @@
|
||||
name: Run commands when issues are labeled or comments added
|
||||
on:
|
||||
issues:
|
||||
types: [labeled]
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Actions
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: "grafana/grafana-github-actions"
|
||||
path: ./actions
|
||||
ref: main
|
||||
- name: Install Actions
|
||||
run: npm install --production --prefix ./actions
|
||||
- name: Run Commands
|
||||
uses: ./actions/commands
|
||||
with:
|
||||
metricsWriteAPIKey: ${{secrets.GRAFANA_MISC_STATS_API_KEY}}
|
||||
token: ${{secrets.GH_BOT_ACCESS_TOKEN}}
|
||||
configPath: commands
|
||||
24
.github/workflows/github-release.yml
vendored
24
.github/workflows/github-release.yml
vendored
@@ -1,24 +0,0 @@
|
||||
name: Create or update GitHub release
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
required: true
|
||||
description: Needs to match, exactly, the name of a milestone (NO v prefix)
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Actions
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: "grafana/grafana-github-actions"
|
||||
path: ./actions
|
||||
ref: main
|
||||
- name: Install Actions
|
||||
run: npm install --production --prefix ./actions
|
||||
- name: Run github release action
|
||||
uses: ./actions/github-release
|
||||
with:
|
||||
token: ${{secrets.GH_BOT_ACCESS_TOKEN}}
|
||||
metricsWriteAPIKey: ${{secrets.GRAFANA_MISC_STATS_API_KEY}}
|
||||
35
.github/workflows/metrics-collector.yml
vendored
35
.github/workflows/metrics-collector.yml
vendored
@@ -1,35 +0,0 @@
|
||||
#
|
||||
# When triggered by the cron job it will also collect metrics for:
|
||||
# * number of issues without label
|
||||
# * number of issues with "needs more info"
|
||||
# * number of issues with "needs investigation"
|
||||
# * number of issues with label type/bug
|
||||
# * number of open issues in current milestone
|
||||
#
|
||||
# https://github.com/grafana/grafana-github-actions/blob/main/metrics-collector/index.ts
|
||||
#
|
||||
name: Github issue metrics collection
|
||||
on:
|
||||
schedule:
|
||||
- cron: "*/10 * * * *"
|
||||
issues:
|
||||
types: [opened, closed]
|
||||
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Actions
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: "grafana/grafana-github-actions"
|
||||
path: ./actions
|
||||
ref: main
|
||||
- name: Install Actions
|
||||
run: npm install --production --prefix ./actions
|
||||
- name: Run metrics collector
|
||||
uses: ./actions/metrics-collector
|
||||
with:
|
||||
metricsWriteAPIKey: ${{secrets.GRAFANA_MISC_STATS_API_KEY}}
|
||||
token: ${{secrets.GH_BOT_ACCESS_TOKEN}}
|
||||
configPath: "metrics-collector"
|
||||
25
.github/workflows/pr-commands.yml
vendored
25
.github/workflows/pr-commands.yml
vendored
@@ -1,25 +0,0 @@
|
||||
name: PR automation
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Actions
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: "grafana/grafana-github-actions"
|
||||
path: ./actions
|
||||
ref: main
|
||||
- name: Install Actions
|
||||
run: npm install --production --prefix ./actions
|
||||
- name: Run Commands
|
||||
uses: ./actions/commands
|
||||
with:
|
||||
metricsWriteAPIKey: ${{secrets.GRAFANA_MISC_STATS_API_KEY}}
|
||||
token: ${{secrets.GH_BOT_ACCESS_TOKEN}}
|
||||
configPath: pr-commands
|
||||
24
.github/workflows/update-changelog.yml
vendored
24
.github/workflows/update-changelog.yml
vendored
@@ -1,24 +0,0 @@
|
||||
name: Update changelog
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
required: true
|
||||
description: Needs to match, exactly, the name of a milestone
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Actions
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: "grafana/grafana-github-actions"
|
||||
path: ./actions
|
||||
ref: main
|
||||
- name: Install Actions
|
||||
run: npm install --production --prefix ./actions
|
||||
- name: Run update changelog
|
||||
uses: ./actions/update-changelog
|
||||
with:
|
||||
token: ${{secrets.GH_BOT_ACCESS_TOKEN}}
|
||||
metricsWriteAPIKey: ${{secrets.GRAFANA_MISC_STATS_API_KEY}}
|
||||
65
.gitignore
vendored
65
.gitignore
vendored
@@ -8,26 +8,9 @@ awsconfig
|
||||
/dist
|
||||
/public/build
|
||||
/public/views/index.html
|
||||
/public/views/error.html
|
||||
/emails/dist
|
||||
/reports
|
||||
/e2e/tmp
|
||||
.yarnrc
|
||||
.yarn/
|
||||
vendor/
|
||||
/docs/menu.yaml
|
||||
/requests
|
||||
|
||||
# Enterprise emails
|
||||
/emails/templates/enterprise_*
|
||||
/public/emails/enterprise_*
|
||||
|
||||
# Enterprise reporting fonts
|
||||
/public/fonts/dejavu
|
||||
|
||||
# Enterprise devenv
|
||||
/devenv/docker/blocks/grafana-enterprise
|
||||
|
||||
/public_gen
|
||||
/public/vendor/npm
|
||||
/tmp
|
||||
tools/phantomjs/phantomjs
|
||||
tools/phantomjs/phantomjs.exe
|
||||
@@ -51,20 +34,17 @@ public/css/*.min.css
|
||||
.DS_Store
|
||||
.vscode/
|
||||
.vs/
|
||||
.eslintcache
|
||||
|
||||
/data/*
|
||||
/bin/*
|
||||
|
||||
# devenv
|
||||
/devenv/docker-compose.yaml
|
||||
/devenv/.env
|
||||
|
||||
conf/custom.ini
|
||||
fig.yml
|
||||
devenv/docker-compose.yml
|
||||
devenv/docker-compose.yaml
|
||||
/conf/provisioning/**/custom.yaml
|
||||
/conf/provisioning/**/dev.yaml
|
||||
/conf/ldap_dev.toml
|
||||
/conf/ldap_freeipa.toml
|
||||
profile.cov
|
||||
/grafana
|
||||
/local
|
||||
@@ -73,9 +53,7 @@ profile.cov
|
||||
/pkg/cmd/grafana-cli/grafana-cli
|
||||
/pkg/cmd/grafana-server/grafana-server
|
||||
/pkg/cmd/grafana-server/debug
|
||||
/pkg/extensions/*
|
||||
!/pkg/extensions/main.go
|
||||
/public/app/extensions
|
||||
/pkg/extensions
|
||||
debug.test
|
||||
/examples/*/dist
|
||||
/packaging/**/*.rpm
|
||||
@@ -90,39 +68,10 @@ debug.test
|
||||
/vendor/**/*.yml
|
||||
/vendor/**/*_test.go
|
||||
/vendor/**/.editorconfig
|
||||
/vendor/**/appengine*
|
||||
*.orig
|
||||
|
||||
/devenv/bulk-dashboards/*.json
|
||||
/devenv/bulk_alerting_dashboards/*.json
|
||||
/devenv/datasources_bulk.yaml
|
||||
/devenv/bulk_alerting_dashboards/bulk_alerting_datasources.yaml
|
||||
|
||||
/scripts/build/release_publisher/release_publisher
|
||||
*.patch
|
||||
|
||||
# Ignoring frontend packages specifics
|
||||
/packages/**/dist
|
||||
/packages/**/compiled
|
||||
/packages/**/.rpt2_cache
|
||||
/packages/**/tsdoc-metadata.json
|
||||
|
||||
# Ignore go local build dependencies
|
||||
/scripts/go/bin/**
|
||||
|
||||
# Ignore compilation stats from `yarn stats`
|
||||
compilation-stats.json
|
||||
|
||||
# e2e tests
|
||||
/packages/grafana-e2e/cypress/screenshots
|
||||
/packages/grafana-e2e/cypress/videos
|
||||
/packages/grafana-e2e/cypress/logs
|
||||
/e2e/server.log
|
||||
/e2e/**/screenshots
|
||||
!/e2e/**/screenshots/expected/*
|
||||
/e2e/**/videos/*
|
||||
|
||||
# report dumping the whole system env
|
||||
/report.*.json
|
||||
|
||||
# auto generated frontend docs
|
||||
/docs/sources/packages_api
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
.git
|
||||
.github
|
||||
dist/
|
||||
pkg/
|
||||
node_modules
|
||||
public/vendor/
|
||||
vendor/
|
||||
data/
|
||||
e2e/tmp
|
||||
public/build/
|
||||
public/sass/*.generated.scss
|
||||
devenv/
|
||||
@@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
...require('@grafana/toolkit/src/config/prettier.plugin.config.json'),
|
||||
};
|
||||
4931
CHANGELOG.md
4931
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
2257
CHANGELOG_ARCHIVE.md
2257
CHANGELOG_ARCHIVE.md
File diff suppressed because it is too large
Load Diff
@@ -2,25 +2,25 @@
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
- Using welcoming and inclusive language
|
||||
- Being respectful of differing viewpoints and experiences
|
||||
- Gracefully accepting constructive criticism
|
||||
- Focusing on what is best for the community
|
||||
- Showing empathy towards other community members
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
- The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
- Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
@@ -34,7 +34,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at conduct@grafana.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at contact@grafana.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
# Contributing to Grafana
|
||||
|
||||
Thank you for your interest in contributing to Grafana! We welcome all people who want to contribute in a healthy and constructive manner within our community. To help us create a safe and positive community experience for all, we require all participants to adhere to the [Code of Conduct](CODE_OF_CONDUCT.md).
|
||||
|
||||
This document is a guide to help you through the process of contributing to Grafana.
|
||||
|
||||
## Become a contributor
|
||||
|
||||
You can contribute to Grafana in several ways. Here are some examples:
|
||||
|
||||
- Contribute to the Grafana codebase.
|
||||
- Report and triage bugs.
|
||||
- Develop community plugins and dashboards.
|
||||
- Write technical documentation and blog posts, for users and contributors.
|
||||
- Organize meetups and user groups in your local area.
|
||||
- Help others by answering questions about Grafana.
|
||||
|
||||
For more ways to contribute, check out the [Open Source Guides](https://opensource.guide/how-to-contribute/).
|
||||
|
||||
### Report bugs
|
||||
|
||||
Before submitting a new issue, try to make sure someone hasn't already reported the problem. Look through the [existing issues](https://github.com/grafana/grafana/issues) for similar issues.
|
||||
|
||||
Report a bug by submitting a [bug report](https://github.com/grafana/grafana/issues/new?labels=type%3A+bug&template=1-bug_report.md). Make sure that you provide as much information as possible on how to reproduce the bug.
|
||||
|
||||
Follow the issue template and add additional information that will help us replicate the problem.
|
||||
|
||||
For data visualization issues:
|
||||
- Query results from the inspect drawer (data tab & query inspector)
|
||||
- Panel settings can be extracted in the panel inspect drawer JSON tab
|
||||
|
||||
For a dashboard related issues:
|
||||
- Dashboard JSON can be found in the dashboard settings JSON model view
|
||||
|
||||
For authentication and alerting Grafana server logs are useful.
|
||||
|
||||
#### Security issues
|
||||
|
||||
If you believe you've found a security vulnerability, please read our [security policy](https://github.com/grafana/grafana/security/policy) for more details.
|
||||
|
||||
### Suggest enhancements
|
||||
|
||||
If you have an idea of how to improve Grafana, submit an [enhancement request](https://github.com/grafana/grafana/issues/new?labels=type%3A+feature+request&template=2-feature_request.md).
|
||||
|
||||
We want to make Grafana accessible to even more people. Submit an [accessibility issue](https://github.com/grafana/grafana/issues/new?labels=type%3A+accessibility&template=3-accessibility.md) to help us understand what we can improve.
|
||||
|
||||
### Triage issues
|
||||
|
||||
If you don't have the knowledge or time to code, consider helping with _issue triage_. The community will thank you for saving them time by spending some of yours.
|
||||
|
||||
Read more about the ways you can [Triage issues](/contribute/triage-issues.md).
|
||||
|
||||
### Answering questions
|
||||
|
||||
If you have a question and you can't find the answer in the [documentation](https://grafana.com/docs/), the next step is to ask it on the [community site](https://community.grafana.com/).
|
||||
|
||||
It's important to us to help these users, and we'd love your help. Sign up to our [community site](https://community.grafana.com/), and start helping other Grafana users by answering their questions.
|
||||
|
||||
### Your first contribution
|
||||
|
||||
Unsure where to begin contributing to Grafana? Start by browsing issues labeled `beginner friendly` or `help wanted`.
|
||||
|
||||
- [Beginner-friendly](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3A%22beginner+friendly%22) issues are generally straightforward to complete.
|
||||
- [Help wanted](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) issues are problems we would like the community to help us with regardless of complexity.
|
||||
|
||||
If you're looking to make a code change, see how to set up your environment for [local development](contribute/developer-guide.md).
|
||||
|
||||
When you're ready to contribute, it's time to [Create a pull request](/contribute/create-pull-request.md).
|
||||
|
||||
#### Contributor License Agreement (CLA)
|
||||
|
||||
Before we can accept your pull request, you need to [sign our CLA](https://grafana.com/docs/grafana/latest/developers/cla/). If you haven't, our CLA assistant prompts you to when you create your pull request.
|
||||
|
||||
## Where do I go from here?
|
||||
|
||||
- Set up your [development environment](contribute/developer-guide.md).
|
||||
- Learn how to [contribute documentation](contribute/documentation.md).
|
||||
- Get started [developing plugins](https://grafana.com/docs/grafana/latest/developers/plugins/) for Grafana.
|
||||
- Look through the resources in the [contribute](https://github.com/grafana/grafana/tree/main/contribute) folder.
|
||||
87
Dockerfile
87
Dockerfile
@@ -1,48 +1,46 @@
|
||||
FROM node:14.16.0-alpine3.13 as js-builder
|
||||
# Golang build container
|
||||
FROM golang:1.11
|
||||
|
||||
WORKDIR $GOPATH/src/github.com/grafana/grafana
|
||||
|
||||
COPY Gopkg.toml Gopkg.lock ./
|
||||
COPY vendor vendor
|
||||
|
||||
ARG DEP_ENSURE=""
|
||||
RUN if [ ! -z "${DEP_ENSURE}" ]; then \
|
||||
go get -u github.com/golang/dep/cmd/dep && \
|
||||
dep ensure --vendor-only; \
|
||||
fi
|
||||
|
||||
COPY pkg pkg
|
||||
COPY build.go build.go
|
||||
COPY package.json package.json
|
||||
|
||||
RUN go run build.go build
|
||||
|
||||
# Node build container
|
||||
FROM node:8
|
||||
|
||||
WORKDIR /usr/src/app/
|
||||
|
||||
COPY package.json yarn.lock ./
|
||||
COPY packages packages
|
||||
|
||||
RUN apk --no-cache add git
|
||||
RUN yarn install --pure-lockfile --no-progress
|
||||
|
||||
COPY tsconfig.json .eslintrc .editorconfig .browserslistrc .prettierrc.js ./
|
||||
COPY Gruntfile.js tsconfig.json tslint.json ./
|
||||
COPY public public
|
||||
COPY tools tools
|
||||
COPY scripts scripts
|
||||
COPY emails emails
|
||||
|
||||
ENV NODE_ENV production
|
||||
RUN yarn build
|
||||
RUN ./node_modules/.bin/grunt build
|
||||
|
||||
FROM golang:1.16.1-alpine3.13 as go-builder
|
||||
|
||||
RUN apk add --no-cache gcc g++
|
||||
|
||||
WORKDIR $GOPATH/src/github.com/grafana/grafana
|
||||
|
||||
COPY go.mod go.sum embed.go ./
|
||||
|
||||
RUN go mod verify
|
||||
|
||||
COPY cue cue
|
||||
COPY public/app/plugins public/app/plugins
|
||||
COPY pkg pkg
|
||||
COPY build.go package.json ./
|
||||
|
||||
RUN go run build.go build
|
||||
|
||||
# Final stage
|
||||
FROM alpine:3.13
|
||||
|
||||
LABEL maintainer="Grafana team <hello@grafana.com>"
|
||||
# Final container
|
||||
FROM debian:stretch-slim
|
||||
|
||||
ARG GF_UID="472"
|
||||
ARG GF_GID="0"
|
||||
ARG GF_GID="472"
|
||||
|
||||
ENV PATH="/usr/share/grafana/bin:$PATH" \
|
||||
ENV PATH=/usr/share/grafana/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
|
||||
GF_PATHS_CONFIG="/etc/grafana/grafana.ini" \
|
||||
GF_PATHS_DATA="/var/lib/grafana" \
|
||||
GF_PATHS_HOME="/usr/share/grafana" \
|
||||
@@ -52,34 +50,29 @@ ENV PATH="/usr/share/grafana/bin:$PATH" \
|
||||
|
||||
WORKDIR $GF_PATHS_HOME
|
||||
|
||||
RUN apk add --no-cache ca-certificates bash tzdata && \
|
||||
apk add --no-cache openssl musl-utils
|
||||
RUN apt-get update && apt-get install -qq -y libfontconfig ca-certificates && \
|
||||
apt-get autoremove -y && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY conf ./conf
|
||||
|
||||
RUN if [ ! $(getent group "$GF_GID") ]; then \
|
||||
addgroup -S -g $GF_GID grafana; \
|
||||
fi
|
||||
|
||||
RUN export GF_GID_NAME=$(getent group $GF_GID | cut -d':' -f1) && \
|
||||
mkdir -p "$GF_PATHS_HOME/.aws" && \
|
||||
adduser -S -u $GF_UID -G "$GF_GID_NAME" grafana && \
|
||||
RUN mkdir -p "$GF_PATHS_HOME/.aws" && \
|
||||
groupadd -r -g $GF_GID grafana && \
|
||||
useradd -r -u $GF_UID -g grafana grafana && \
|
||||
mkdir -p "$GF_PATHS_PROVISIONING/datasources" \
|
||||
"$GF_PATHS_PROVISIONING/dashboards" \
|
||||
"$GF_PATHS_PROVISIONING/notifiers" \
|
||||
"$GF_PATHS_PROVISIONING/plugins" \
|
||||
"$GF_PATHS_PROVISIONING/access-control" \
|
||||
"$GF_PATHS_LOGS" \
|
||||
"$GF_PATHS_PLUGINS" \
|
||||
"$GF_PATHS_DATA" && \
|
||||
cp "$GF_PATHS_HOME/conf/sample.ini" "$GF_PATHS_CONFIG" && \
|
||||
cp "$GF_PATHS_HOME/conf/ldap.toml" /etc/grafana/ldap.toml && \
|
||||
chown -R "grafana:$GF_GID_NAME" "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING" && \
|
||||
chmod -R 777 "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING"
|
||||
chown -R grafana:grafana "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" && \
|
||||
chmod 777 "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS"
|
||||
|
||||
COPY --from=go-builder /go/src/github.com/grafana/grafana/bin/*/grafana-server /go/src/github.com/grafana/grafana/bin/*/grafana-cli ./bin/
|
||||
COPY --from=js-builder /usr/src/app/public ./public
|
||||
COPY --from=js-builder /usr/src/app/tools ./tools
|
||||
COPY --from=0 /go/src/github.com/grafana/grafana/bin/linux-amd64/grafana-server /go/src/github.com/grafana/grafana/bin/linux-amd64/grafana-cli ./bin/
|
||||
COPY --from=1 /usr/src/app/public ./public
|
||||
COPY --from=1 /usr/src/app/tools ./tools
|
||||
COPY tools/phantomjs/render.js ./tools/phantomjs/render.js
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
FROM node:14.15.1-slim AS js-builder
|
||||
|
||||
WORKDIR /usr/src/app/
|
||||
|
||||
COPY package.json yarn.lock ./
|
||||
COPY packages packages
|
||||
|
||||
RUN apt-get update && apt-get install -yq git
|
||||
RUN yarn install --pure-lockfile
|
||||
|
||||
COPY tsconfig.json .eslintrc .editorconfig .browserslistrc .prettierrc.js ./
|
||||
COPY public public
|
||||
COPY tools tools
|
||||
COPY scripts scripts
|
||||
COPY emails emails
|
||||
|
||||
ENV NODE_ENV production
|
||||
RUN yarn build
|
||||
|
||||
FROM golang:1.16 AS go-builder
|
||||
|
||||
WORKDIR /src/grafana
|
||||
|
||||
COPY go.mod go.sum embed.go ./
|
||||
|
||||
RUN go mod verify
|
||||
|
||||
COPY build.go package.json ./
|
||||
COPY pkg pkg/
|
||||
COPY cue cue/
|
||||
COPY public/app/plugins public/app/plugins/
|
||||
|
||||
RUN go run build.go build
|
||||
|
||||
FROM ubuntu:20.04
|
||||
|
||||
LABEL maintainer="Grafana team <hello@grafana.com>"
|
||||
EXPOSE 3000
|
||||
|
||||
ARG GF_UID="472"
|
||||
ARG GF_GID="472"
|
||||
|
||||
ENV PATH="/usr/share/grafana/bin:$PATH" \
|
||||
GF_PATHS_CONFIG="/etc/grafana/grafana.ini" \
|
||||
GF_PATHS_DATA="/var/lib/grafana" \
|
||||
GF_PATHS_HOME="/usr/share/grafana" \
|
||||
GF_PATHS_LOGS="/var/log/grafana" \
|
||||
GF_PATHS_PLUGINS="/var/lib/grafana/plugins" \
|
||||
GF_PATHS_PROVISIONING="/etc/grafana/provisioning"
|
||||
|
||||
WORKDIR $GF_PATHS_HOME
|
||||
|
||||
COPY conf conf
|
||||
|
||||
# curl should be part of the image
|
||||
RUN apt-get update && apt-get install -y ca-certificates curl
|
||||
|
||||
RUN mkdir -p "$GF_PATHS_HOME/.aws" && \
|
||||
addgroup --system --gid $GF_GID grafana && \
|
||||
adduser --uid $GF_UID --system --ingroup grafana grafana && \
|
||||
mkdir -p "$GF_PATHS_PROVISIONING/datasources" \
|
||||
"$GF_PATHS_PROVISIONING/dashboards" \
|
||||
"$GF_PATHS_PROVISIONING/notifiers" \
|
||||
"$GF_PATHS_PROVISIONING/plugins" \
|
||||
"$GF_PATHS_PROVISIONING/access-control" \
|
||||
"$GF_PATHS_LOGS" \
|
||||
"$GF_PATHS_PLUGINS" \
|
||||
"$GF_PATHS_DATA" && \
|
||||
cp conf/sample.ini "$GF_PATHS_CONFIG" && \
|
||||
cp conf/ldap.toml /etc/grafana/ldap.toml && \
|
||||
chown -R grafana:grafana "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING" && \
|
||||
chmod -R 777 "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING"
|
||||
|
||||
COPY --from=go-builder /src/grafana/bin/*/grafana-server /src/grafana/bin/*/grafana-cli bin/
|
||||
COPY --from=js-builder /usr/src/app/public public
|
||||
COPY --from=js-builder /usr/src/app/tools tools
|
||||
|
||||
COPY packaging/docker/run.sh /
|
||||
|
||||
USER grafana
|
||||
ENTRYPOINT [ "/run.sh" ]
|
||||
205
GOVERNANCE.md
205
GOVERNANCE.md
@@ -1,205 +0,0 @@
|
||||
# Governance
|
||||
|
||||
This document describes the rules and governance of the project. It is meant to be followed by all the developers of the project and the Grafana community. Common terminology used in this governance document are listed below:
|
||||
|
||||
- **Team members**: Any members of the private [grafana-team][team] Google group.
|
||||
|
||||
- **Maintainers**: Maintainers lead an individual project or parts thereof ([`MAINTAINERS.md`][maintainers]).
|
||||
|
||||
- **Projects**: A single repository in the Grafana GitHub organization and listed below is referred to as a project:
|
||||
|
||||
- clock-panel
|
||||
- devtools
|
||||
- gel-app
|
||||
- grafana
|
||||
- grafana-github-datasource
|
||||
- grafana-image-renderer
|
||||
- grafana-kiosk
|
||||
- grafana-plugin-sdk-go
|
||||
- grafana-polystat-panel
|
||||
- grafonnet-lib
|
||||
- kairosdb-datasource
|
||||
- piechart-panel
|
||||
- simple-angular-panel
|
||||
- simple-app-plugin
|
||||
- simple-datasource
|
||||
- simple-datasource-backend
|
||||
- simple-json-backend-datasource
|
||||
- simple-json-datasource
|
||||
- simple-react-panel
|
||||
- strava-datasource
|
||||
- tutorials
|
||||
- worldmap-panel
|
||||
|
||||
- **The Grafana project**: The sum of all activities performed under this governance, concerning one or more repositories or the community.
|
||||
|
||||
## Values
|
||||
|
||||
The Grafana developers and community are expected to follow the values defined in the Grafana Code of Conduct. Furthermore, the Grafana community strives for kindness, giving feedback effectively, and building a welcoming environment. The Grafana developers generally decide by consensus and only resort to conflict resolution by a majority vote if consensus cannot be reached.
|
||||
|
||||
## Projects
|
||||
|
||||
Each project must have a [`MAINTAINERS.md`][maintainers] file with at least one maintainer. Where a project has a release process, access and documentation should be such that more than one person can perform a release. Releases should be announced on the Grafana Labs blog. Any new projects should be first proposed on the [team mailing list][team] following the voting procedures listed below.
|
||||
|
||||
## Decision making
|
||||
|
||||
### Team members
|
||||
|
||||
Team member status may be given to those who have made ongoing contributions to the Grafana project for at least 3 months. This is usually in the form of code improvements and/or notable work on documentation, but organizing events or user support could also be taken into account.
|
||||
|
||||
New members may be proposed by any existing member by email to [grafana-team][team]. It is highly desirable to reach consensus about acceptance of a new member. However, the proposal is ultimately voted on by a formal [supermajority vote](#supermajority-vote).
|
||||
|
||||
If the new member proposal is accepted, the proposed team member should be contacted privately via email to confirm or deny their acceptance of team membership. This email will also be CC'd to [grafana-team][team] for record-keeping purposes.
|
||||
|
||||
If they choose to accept, the [onboarding](#onboarding) procedure is followed.
|
||||
|
||||
Team members may retire at any time by emailing [the team][team].
|
||||
|
||||
Team members can be removed by [supermajority vote](#supermajority-vote) on [the team mailing list][team].
|
||||
For this vote, the member in question is not eligible to vote and does not count towards the quorum.
|
||||
Any removal vote can cover only one single person.
|
||||
|
||||
Upon death of a member, they leave the team automatically.
|
||||
|
||||
In case a member leaves, the [offboarding](#offboarding) procedure is applied.
|
||||
|
||||
The current team members are:
|
||||
|
||||
- Alexander Zobnin ([Grafana Labs](https://grafana.com/))
|
||||
- Alex Khomenko ([Grafana Labs](https://grafana.com/))
|
||||
- Andrej Ocenas ([Grafana Labs](https://grafana.com/))
|
||||
- Arve Knudsen ([Grafana Labs](https://grafana.com/))
|
||||
- Brian Gann ([Grafana Labs](https://grafana.com/))
|
||||
- Carl Bergquist ([Grafana Labs](https://grafana.com/))
|
||||
- Chris Trott ([Grafana Labs](https://grafana.com/))
|
||||
- Daniel Lee ([Grafana Labs](https://grafana.com/))
|
||||
- David Kaltschmidt ([Grafana Labs](https://grafana.com/))
|
||||
- Diana Payton ([Grafana Labs](https://grafana.com/))
|
||||
- Diana Sarlinska ([Grafana Labs](https://grafana.com/))
|
||||
- Dominik Prokop ([Grafana Labs](https://grafana.com/))
|
||||
- Emil Tullstedt ([Grafana Labs](https://grafana.com/))
|
||||
- Fredrik Enestad ([Soundtrack Your Brand](https://www.soundtrackyourbrand.com/))
|
||||
- Hugo Häggmark ([Grafana Labs](https://grafana.com/))
|
||||
- Ivana Huckova ([Grafana Labs](https://grafana.com/))
|
||||
- Jeroen Op 't Eynde ([Grafana Labs](https://grafana.com/))
|
||||
- Jessica Müller ([Grafana Labs](https://grafana.com/))
|
||||
- Julien Pivotto ([Inuits](https://inuits.eu/))
|
||||
- Kay Delaney ([Grafana Labs](https://grafana.com/))
|
||||
- Kyle Brandt ([Grafana Labs](https://grafana.com/))
|
||||
- Leonard Gram ([Grafana Labs](https://grafana.com/))
|
||||
- Lukas Siatka ([Grafana Labs](https://grafana.com/))
|
||||
- Malcolm Holmes ([Grafana Labs](https://grafana.com/))
|
||||
- Marcus Andersson ([Grafana Labs](https://grafana.com/))
|
||||
- Marcus Efraimsson ([Grafana Labs](https://grafana.com/))
|
||||
- Marcus Olsson ([Grafana Labs](https://grafana.com/))
|
||||
- Mitsuhiro Tanda ([GREE](https://corp.gree.net/jp/en/))
|
||||
- Patrick O’Carroll ([Grafana Labs](https://grafana.com/))
|
||||
- Peter Holmberg ([Grafana Labs](https://grafana.com/))
|
||||
- Richard Hartmann ([Grafana Labs](https://grafana.com/))
|
||||
- Ryan McKinley ([Grafana Labs](https://grafana.com/))
|
||||
- Sofia Papagiannaki ([Grafana Labs](https://grafana.com/))
|
||||
- Stephanie Closson ([Grafana Labs](https://grafana.com/))
|
||||
- Tobias Skarhed ([Grafana Labs](https://grafana.com/))
|
||||
- Torkel Ödegaard ([Grafana Labs](https://grafana.com/))
|
||||
- Utkarsh Bhatnagar ([Tinder](https://www.tinder.com/))
|
||||
|
||||
### Maintainers
|
||||
|
||||
Maintainers lead one or more project(s) or parts thereof and serve as a point of conflict resolution amongst the contributors to this project. Ideally, maintainers are also team members, but exceptions are possible for suitable maintainers that, for whatever reason, are not yet team members.
|
||||
|
||||
Changes in maintainership have to be announced on the [developers mailing list][devs]. They are decided by [rough consensus](#consensus) and formalized by changing the [`MAINTAINERS.md`][maintainers] file of the respective repository.
|
||||
|
||||
Maintainers are granted commit rights to all projects covered by this governance.
|
||||
|
||||
A maintainer or committer may resign by notifying the [team mailing list][team]. A maintainer with no project activity for a year is considered to have resigned. Maintainers that wish to resign are encouraged to propose another team member to take over the project.
|
||||
|
||||
A project may have multiple maintainers, as long as the responsibilities are clearly agreed upon between them. This includes coordinating who handles which issues and pull requests.
|
||||
|
||||
### Technical decisions
|
||||
|
||||
Technical decisions that only affect a single project are made informally by the maintainer of this project, and [rough consensus](#consensus) is assumed. Technical decisions that span multiple parts of the Grafana project should be discussed and made on the [Grafana developer mailing list][devs].
|
||||
|
||||
Decisions are usually made by [rough consensus](#consensus). If no consensus can be reached, the matter may be resolved by [majority vote](#majority-vote).
|
||||
|
||||
### Governance changes
|
||||
|
||||
Changes to this document are made by Grafana Labs.
|
||||
|
||||
### Other matters
|
||||
|
||||
Any matter that needs a decision may be called to a vote by any member if they deem it necessary. For private or personnel matters, discussion and voting takes place on the [team mailing list][team], otherwise on the [developer mailing list][devs].
|
||||
|
||||
## Voting
|
||||
|
||||
The Grafana project usually runs by informal consensus, however sometimes a formal decision must be made.
|
||||
|
||||
Depending on the subject matter, as laid out [above](#decision-making), different methods of voting are used.
|
||||
|
||||
For all votes, voting must be open for at least one week. The end date should be clearly stated in the call to vote. A vote may be called and closed early if enough votes have come in one way so that further votes cannot change the final decision.
|
||||
|
||||
In all cases, all and only [team members](#team-members) are eligible to vote, with the sole exception of the forced removal of a team member, in which said member is not eligible to vote.
|
||||
|
||||
Discussion and votes on personnel matters (including but not limited to team membership and maintainership) are held in private on the [team mailing list][team]. All other discussion and votes are held in public on the [developer mailing list][devs].
|
||||
|
||||
For public discussions, anyone interested is encouraged to participate. Formal power to object or vote is limited to [team members](#team-members).
|
||||
|
||||
### Consensus
|
||||
|
||||
The default decision making mechanism for the Grafana project is [rough][rough] consensus. This means that any decision on technical issues is considered supported by the [team][team] as long as nobody objects or the objection has been considered but not necessarily accommodated.
|
||||
|
||||
Silence on any consensus decision is implicit agreement and equivalent to explicit agreement. Explicit agreement may be stated at will. Decisions may, but do not need to be called out and put up for decision on the [developers mailing list][devs] at any time and by anyone.
|
||||
|
||||
Consensus decisions can never override or go against the spirit of an earlier explicit vote.
|
||||
|
||||
If any [team member](#team-members) raises objections, the team members work together towards a solution that all involved can accept. This solution is again subject to rough consensus.
|
||||
|
||||
In case no consensus can be found, but a decision one way or the other must be made, any [team member](#team-members) may call a formal [majority vote](#majority-vote).
|
||||
|
||||
### Majority vote
|
||||
|
||||
Majority votes must be called explicitly in a separate thread on the appropriate mailing list. The subject must be prefixed with `[VOTE]`. In the body, the call to vote must state the proposal being voted on. It should reference any discussion leading up to this point.
|
||||
|
||||
Votes may take the form of a single proposal, with the option to vote yes or no, or the form of multiple alternatives.
|
||||
|
||||
A vote on a single proposal is considered successful if more vote in favor than against.
|
||||
|
||||
If there are multiple alternatives, members may vote for one or more alternatives, or vote “no” to object to all alternatives. It is not possible to cast an “abstain” vote. A vote on multiple alternatives is considered decided in favor of one alternative if it has received the most votes in favor, and a vote from more than half of those voting. Should no alternative reach this quorum, another vote on a reduced number of options may be called separately.
|
||||
|
||||
### Supermajority vote
|
||||
|
||||
Supermajority votes must be called explicitly in a separate thread on the appropriate mailing list. The subject must be prefixed with `[VOTE]`. In the body, the call to vote must state the proposal being voted on. It should reference any discussion leading up to this point.
|
||||
|
||||
Votes may take the form of a single proposal, with the option to vote yes or no, or the form of multiple alternatives.
|
||||
|
||||
A vote on a single proposal is considered successful if at least two thirds of those eligible to vote vote in favor.
|
||||
|
||||
If there are multiple alternatives, members may vote for one or more alternatives, or vote “no” to object to all alternatives. A vote on multiple alternatives is considered decided in favor of one alternative if it has received the most votes in favor, and a vote from at least two thirds of those eligible to vote. Should no alternative reach this quorum, another vote on a reduced number of options may be called separately.
|
||||
|
||||
## On- / Offboarding
|
||||
|
||||
### Onboarding
|
||||
|
||||
The new member is
|
||||
|
||||
- added to the list of [team members](#team-members). Ideally by sending a PR of their own, at least approving said PR.
|
||||
- announced on the [developers mailing list][devs] by an existing team member. Ideally, the new member replies in this thread, acknowledging team membership.
|
||||
- added to the projects with commit rights.
|
||||
- added to the [team mailing list][team].
|
||||
|
||||
### Offboarding
|
||||
|
||||
The ex-member is
|
||||
|
||||
- removed from the list of [team members](#team-members). Ideally by sending a PR of their own, at least approving said PR. In case of forced removal, no approval is needed.
|
||||
- removed from the projects. Optionally, they can retain maintainership of one or more repositories if the [team](#team-members) agrees.
|
||||
- removed from the team mailing list and demoted to a normal member of the other mailing lists.
|
||||
- not allowed to call themselves an active team member any more, nor allowed to imply this to be the case.
|
||||
- added to a list of previous members if they so choose.
|
||||
|
||||
If needed, we reserve the right to publicly announce removal.
|
||||
|
||||
[coc]: https://github.com/grafana/grafana/blob/main/CODE_OF_CONDUCT.md
|
||||
[devs]: https://groups.google.com/forum/#!forum/grafana-developers
|
||||
[maintainers]: https://github.com/grafana/grafana/blob/main/MAINTAINERS.md
|
||||
[rough]: https://tools.ietf.org/html/rfc7282
|
||||
[team]: https://groups.google.com/forum/#!forum/grafana-team
|
||||
684
Gopkg.lock
generated
Normal file
684
Gopkg.lock
generated
Normal file
@@ -0,0 +1,684 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
name = "cloud.google.com/go"
|
||||
packages = ["compute/metadata"]
|
||||
revision = "056a55f54a6cc77b440b31a56a5e7c3982d32811"
|
||||
version = "v0.22.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/BurntSushi/toml"
|
||||
packages = ["."]
|
||||
revision = "b26d9c308763d68093482582cea63d69be07a0f0"
|
||||
version = "v0.3.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/Unknwon/com"
|
||||
packages = ["."]
|
||||
revision = "7677a1d7c1137cd3dd5ba7a076d0c898a1ef4520"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/VividCortex/mysqlerr"
|
||||
packages = ["."]
|
||||
revision = "6c6b55f8796f578c870b7e19bafb16103bc40095"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/aws/aws-sdk-go"
|
||||
packages = [
|
||||
"aws",
|
||||
"aws/awserr",
|
||||
"aws/awsutil",
|
||||
"aws/client",
|
||||
"aws/client/metadata",
|
||||
"aws/corehandlers",
|
||||
"aws/credentials",
|
||||
"aws/credentials/ec2rolecreds",
|
||||
"aws/credentials/endpointcreds",
|
||||
"aws/credentials/stscreds",
|
||||
"aws/csm",
|
||||
"aws/defaults",
|
||||
"aws/ec2metadata",
|
||||
"aws/endpoints",
|
||||
"aws/request",
|
||||
"aws/session",
|
||||
"aws/signer/v4",
|
||||
"internal/sdkio",
|
||||
"internal/sdkrand",
|
||||
"internal/shareddefaults",
|
||||
"private/protocol",
|
||||
"private/protocol/ec2query",
|
||||
"private/protocol/eventstream",
|
||||
"private/protocol/eventstream/eventstreamapi",
|
||||
"private/protocol/query",
|
||||
"private/protocol/query/queryutil",
|
||||
"private/protocol/rest",
|
||||
"private/protocol/restxml",
|
||||
"private/protocol/xml/xmlutil",
|
||||
"service/cloudwatch",
|
||||
"service/ec2",
|
||||
"service/ec2/ec2iface",
|
||||
"service/s3",
|
||||
"service/sts"
|
||||
]
|
||||
revision = "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
version = "v1.14.12"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/benbjohnson/clock"
|
||||
packages = ["."]
|
||||
revision = "7dc76406b6d3c05b5f71a86293cbcf3c4ea03b19"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/beorn7/perks"
|
||||
packages = ["quantile"]
|
||||
revision = "3a771d992973f24aa725d07868b467d1ddfceafb"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/bmizerany/assert"
|
||||
packages = ["."]
|
||||
revision = "b7ed37b82869576c289d7d97fb2bbd8b64a0cb28"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/bradfitz/gomemcache"
|
||||
packages = ["memcache"]
|
||||
revision = "1952afaa557dc08e8e0d89eafab110fb501c1a2b"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/codahale/hdrhistogram"
|
||||
packages = ["."]
|
||||
revision = "3a0bb77429bd3a61596f5e8a3172445844342120"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/codegangsta/cli"
|
||||
packages = ["."]
|
||||
revision = "cfb38830724cc34fedffe9a2a29fb54fa9169cd1"
|
||||
version = "v1.20.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/davecgh/go-spew"
|
||||
packages = ["spew"]
|
||||
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/denisenkom/go-mssqldb"
|
||||
packages = [
|
||||
".",
|
||||
"internal/cp"
|
||||
]
|
||||
revision = "270bc3860bb94dd3a3ffd047377d746c5e276726"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/facebookgo/inject"
|
||||
packages = ["."]
|
||||
revision = "cc1aa653e50f6a9893bcaef89e673e5b24e1e97b"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/facebookgo/structtag"
|
||||
packages = ["."]
|
||||
revision = "217e25fb96916cc60332e399c9aa63f5c422ceed"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/fatih/color"
|
||||
packages = ["."]
|
||||
revision = "5b77d2a35fb0ede96d138fc9a99f5c9b6aef11b4"
|
||||
version = "v1.7.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/go-ini/ini"
|
||||
packages = ["."]
|
||||
revision = "6529cf7c58879c08d927016dde4477f18a0634cb"
|
||||
version = "v1.36.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/go-ldap/ldap"
|
||||
packages = ["."]
|
||||
revision = "bb7a9ca6e4fbc2129e3db588a34bc970ffe811a9"
|
||||
version = "v2.5.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/go-macaron/binding"
|
||||
packages = ["."]
|
||||
revision = "ac54ee249c27dca7e76fad851a4a04b73bd1b183"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/go-macaron/gzip"
|
||||
packages = ["."]
|
||||
revision = "cad1c6580a07c56f5f6bc52d66002a05985c5854"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/go-macaron/inject"
|
||||
packages = ["."]
|
||||
revision = "d8a0b8677191f4380287cfebd08e462217bac7ad"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/go-macaron/session"
|
||||
packages = [
|
||||
".",
|
||||
"memcache",
|
||||
"postgres",
|
||||
"redis"
|
||||
]
|
||||
revision = "b8e286a0dba8f4999042d6b258daf51b31d08938"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/go-sql-driver/mysql"
|
||||
packages = ["."]
|
||||
revision = "2cc627ac8defc45d65066ae98f898166f580f9a4"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/go-stack/stack"
|
||||
packages = ["."]
|
||||
revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc"
|
||||
version = "v1.7.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/go-xorm/builder"
|
||||
packages = ["."]
|
||||
revision = "bad0a612f0d6277b953910822ab5dfb30dd18237"
|
||||
version = "v0.2.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/go-xorm/core"
|
||||
packages = ["."]
|
||||
revision = "da1adaf7a28ca792961721a34e6e04945200c890"
|
||||
version = "v0.5.7"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/go-xorm/xorm"
|
||||
packages = ["."]
|
||||
revision = "1933dd69e294c0a26c0266637067f24dbb25770c"
|
||||
version = "v0.6.4"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = [
|
||||
"proto",
|
||||
"ptypes",
|
||||
"ptypes/any",
|
||||
"ptypes/duration",
|
||||
"ptypes/timestamp"
|
||||
]
|
||||
revision = "927b65914520a8b7d44f5c9057611cfec6b2e2d0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/gopherjs/gopherjs"
|
||||
packages = ["js"]
|
||||
revision = "8dffc02ea1cb8398bb73f30424697c60fcf8d4c5"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gorilla/websocket"
|
||||
packages = ["."]
|
||||
revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gosimple/slug"
|
||||
packages = ["."]
|
||||
revision = "e9f42fa127660e552d0ad2b589868d403a9be7c6"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/grafana/grafana-plugin-model"
|
||||
packages = [
|
||||
"go/datasource",
|
||||
"go/renderer"
|
||||
]
|
||||
revision = "84176c64269d8060f99e750ee8aba6f062753336"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/hashicorp/go-hclog"
|
||||
packages = ["."]
|
||||
revision = "69ff559dc25f3b435631604f573a5fa1efdb6433"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/hashicorp/go-plugin"
|
||||
packages = ["."]
|
||||
revision = "e8d22c780116115ae5624720c9af0c97afe4f551"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/hashicorp/go-version"
|
||||
packages = ["."]
|
||||
revision = "23480c0665776210b5fbbac6eaaee40e3e6a96b7"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/hashicorp/yamux"
|
||||
packages = ["."]
|
||||
revision = "2658be15c5f05e76244154714161f17e3e77de2e"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/inconshreveable/log15"
|
||||
packages = ["."]
|
||||
revision = "0decfc6c20d9ca0ad143b0e89dcaa20f810b4fb3"
|
||||
version = "v2.13"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/jmespath/go-jmespath"
|
||||
packages = ["."]
|
||||
revision = "0b12d6b5"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/jtolds/gls"
|
||||
packages = ["."]
|
||||
revision = "77f18212c9c7edc9bd6a33d383a7b545ce62f064"
|
||||
version = "v4.2.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/klauspost/compress"
|
||||
packages = [
|
||||
"flate",
|
||||
"gzip"
|
||||
]
|
||||
revision = "6c8db69c4b49dd4df1fff66996cf556176d0b9bf"
|
||||
version = "v1.2.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/klauspost/cpuid"
|
||||
packages = ["."]
|
||||
revision = "ae7887de9fa5d2db4eaa8174a7eff2c1ac00f2da"
|
||||
version = "v1.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/klauspost/crc32"
|
||||
packages = ["."]
|
||||
revision = "cb6bfca970f6908083f26f39a79009d608efd5cd"
|
||||
version = "v1.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/kr/pretty"
|
||||
packages = ["."]
|
||||
revision = "73f6ac0b30a98e433b289500d779f50c1a6f0712"
|
||||
version = "v0.1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/kr/text"
|
||||
packages = ["."]
|
||||
revision = "e2ffdb16a802fe2bb95e2e35ff34f0e53aeef34f"
|
||||
version = "v0.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/lib/pq"
|
||||
packages = [
|
||||
".",
|
||||
"oid"
|
||||
]
|
||||
revision = "d34b9ff171c21ad295489235aec8b6626023cd04"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-colorable"
|
||||
packages = ["."]
|
||||
revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072"
|
||||
version = "v0.0.9"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-isatty"
|
||||
packages = ["."]
|
||||
revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39"
|
||||
version = "v0.0.3"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-sqlite3"
|
||||
packages = ["."]
|
||||
revision = "323a32be5a2421b8c7087225079c6c900ec397cd"
|
||||
version = "v1.7.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/matttproud/golang_protobuf_extensions"
|
||||
packages = ["pbutil"]
|
||||
revision = "3247c84500bff8d9fb6d579d800f20b3e091582c"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/mitchellh/go-testing-interface"
|
||||
packages = ["."]
|
||||
revision = "a61a99592b77c9ba629d254a693acffaeb4b7e28"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/oklog/run"
|
||||
packages = ["."]
|
||||
revision = "4dadeb3030eda0273a12382bb2348ffc7c9d1a39"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/opentracing/opentracing-go"
|
||||
packages = [
|
||||
".",
|
||||
"ext",
|
||||
"log"
|
||||
]
|
||||
revision = "1949ddbfd147afd4d964a9f00b24eb291e0e7c38"
|
||||
version = "v1.0.2"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/patrickmn/go-cache"
|
||||
packages = ["."]
|
||||
revision = "a3647f8e31d79543b2d0f0ae2fe5c379d72cedc0"
|
||||
version = "v2.1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/pkg/errors"
|
||||
packages = ["."]
|
||||
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
|
||||
version = "v0.8.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/prometheus/client_golang"
|
||||
packages = [
|
||||
"api",
|
||||
"api/prometheus/v1",
|
||||
"prometheus",
|
||||
"prometheus/promhttp"
|
||||
]
|
||||
revision = "967789050ba94deca04a5e84cce8ad472ce313c1"
|
||||
version = "v0.9.0-pre1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/prometheus/client_model"
|
||||
packages = ["go"]
|
||||
revision = "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/prometheus/common"
|
||||
packages = [
|
||||
"expfmt",
|
||||
"internal/bitbucket.org/ww/goautoneg",
|
||||
"model"
|
||||
]
|
||||
revision = "d811d2e9bf898806ecfb6ef6296774b13ffc314c"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/prometheus/procfs"
|
||||
packages = [
|
||||
".",
|
||||
"internal/util",
|
||||
"nfs",
|
||||
"xfs"
|
||||
]
|
||||
revision = "8b1c2da0d56deffdbb9e48d4414b4e674bd8083e"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/rainycape/unidecode"
|
||||
packages = ["."]
|
||||
revision = "cb7f23ec59bec0d61b19c56cd88cee3d0cc1870c"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/sergi/go-diff"
|
||||
packages = ["diffmatchpatch"]
|
||||
revision = "1744e2970ca51c86172c8190fadad617561ed6e7"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/smartystreets/assertions"
|
||||
packages = [
|
||||
".",
|
||||
"internal/go-render/render",
|
||||
"internal/oglematchers"
|
||||
]
|
||||
revision = "7678a5452ebea5b7090a6b163f844c133f523da2"
|
||||
version = "1.8.3"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/smartystreets/goconvey"
|
||||
packages = [
|
||||
"convey",
|
||||
"convey/gotest",
|
||||
"convey/reporting"
|
||||
]
|
||||
revision = "9e8dc3f972df6c8fcc0375ef492c24d0bb204857"
|
||||
version = "1.6.3"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/teris-io/shortid"
|
||||
packages = ["."]
|
||||
revision = "771a37caa5cf0c81f585d7b6df4dfc77e0615b5c"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/uber/jaeger-client-go"
|
||||
packages = [
|
||||
".",
|
||||
"config",
|
||||
"internal/baggage",
|
||||
"internal/baggage/remote",
|
||||
"internal/spanlog",
|
||||
"internal/throttler",
|
||||
"internal/throttler/remote",
|
||||
"log",
|
||||
"rpcmetrics",
|
||||
"thrift",
|
||||
"thrift-gen/agent",
|
||||
"thrift-gen/baggage",
|
||||
"thrift-gen/jaeger",
|
||||
"thrift-gen/sampling",
|
||||
"thrift-gen/zipkincore",
|
||||
"utils"
|
||||
]
|
||||
revision = "b043381d944715b469fd6b37addfd30145ca1758"
|
||||
version = "v2.14.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/uber/jaeger-lib"
|
||||
packages = ["metrics"]
|
||||
revision = "ed3a127ec5fef7ae9ea95b01b542c47fbd999ce5"
|
||||
version = "v1.5.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/yudai/gojsondiff"
|
||||
packages = [
|
||||
".",
|
||||
"formatter"
|
||||
]
|
||||
revision = "7b1b7adf999dab73a6eb02669c3d82dbb27a3dd6"
|
||||
version = "1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/yudai/golcs"
|
||||
packages = ["."]
|
||||
revision = "ecda9a501e8220fae3b4b600c3db4b0ba22cfc68"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = [
|
||||
"md4",
|
||||
"pbkdf2"
|
||||
]
|
||||
revision = "1a580b3eff7814fc9b40602fd35256c63b50f491"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/net"
|
||||
packages = [
|
||||
"context",
|
||||
"context/ctxhttp",
|
||||
"http/httpguts",
|
||||
"http2",
|
||||
"http2/hpack",
|
||||
"idna",
|
||||
"internal/timeseries",
|
||||
"trace"
|
||||
]
|
||||
revision = "2491c5de3490fced2f6cff376127c667efeed857"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/oauth2"
|
||||
packages = [
|
||||
".",
|
||||
"google",
|
||||
"internal",
|
||||
"jws",
|
||||
"jwt"
|
||||
]
|
||||
revision = "cdc340f7c179dbbfa4afd43b7614e8fcadde4269"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sync"
|
||||
packages = ["errgroup"]
|
||||
revision = "1d60e4601c6fd243af51cc01ddf169918a5407ca"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sys"
|
||||
packages = ["unix"]
|
||||
revision = "7c87d13f8e835d2fb3a70a2912c811ed0c1d241b"
|
||||
|
||||
[[projects]]
|
||||
name = "golang.org/x/text"
|
||||
packages = [
|
||||
"collate",
|
||||
"collate/build",
|
||||
"internal/colltab",
|
||||
"internal/gen",
|
||||
"internal/tag",
|
||||
"internal/triegen",
|
||||
"internal/ucd",
|
||||
"language",
|
||||
"secure/bidirule",
|
||||
"transform",
|
||||
"unicode/bidi",
|
||||
"unicode/cldr",
|
||||
"unicode/norm",
|
||||
"unicode/rangetable"
|
||||
]
|
||||
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
|
||||
version = "v0.3.0"
|
||||
|
||||
[[projects]]
|
||||
name = "google.golang.org/appengine"
|
||||
packages = [
|
||||
".",
|
||||
"cloudsql",
|
||||
"internal",
|
||||
"internal/app_identity",
|
||||
"internal/base",
|
||||
"internal/datastore",
|
||||
"internal/log",
|
||||
"internal/modules",
|
||||
"internal/remote_api",
|
||||
"internal/urlfetch",
|
||||
"urlfetch"
|
||||
]
|
||||
revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "google.golang.org/genproto"
|
||||
packages = ["googleapis/rpc/status"]
|
||||
revision = "7bb2a897381c9c5ab2aeb8614f758d7766af68ff"
|
||||
|
||||
[[projects]]
|
||||
name = "google.golang.org/grpc"
|
||||
packages = [
|
||||
".",
|
||||
"balancer",
|
||||
"balancer/base",
|
||||
"balancer/roundrobin",
|
||||
"codes",
|
||||
"connectivity",
|
||||
"credentials",
|
||||
"encoding",
|
||||
"encoding/proto",
|
||||
"grpclb/grpc_lb_v1/messages",
|
||||
"grpclog",
|
||||
"health",
|
||||
"health/grpc_health_v1",
|
||||
"internal",
|
||||
"keepalive",
|
||||
"metadata",
|
||||
"naming",
|
||||
"peer",
|
||||
"resolver",
|
||||
"resolver/dns",
|
||||
"resolver/passthrough",
|
||||
"stats",
|
||||
"status",
|
||||
"tap",
|
||||
"transport"
|
||||
]
|
||||
revision = "1e2570b1b19ade82d8dbb31bba4e65e9f9ef5b34"
|
||||
version = "v1.11.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "v3"
|
||||
name = "gopkg.in/alexcesaro/quotedprintable.v3"
|
||||
packages = ["."]
|
||||
revision = "2caba252f4dc53eaf6b553000885530023f54623"
|
||||
|
||||
[[projects]]
|
||||
name = "gopkg.in/asn1-ber.v1"
|
||||
packages = ["."]
|
||||
revision = "379148ca0225df7a432012b8df0355c2a2063ac0"
|
||||
version = "v1.2"
|
||||
|
||||
[[projects]]
|
||||
name = "gopkg.in/bufio.v1"
|
||||
packages = ["."]
|
||||
revision = "567b2bfa514e796916c4747494d6ff5132a1dfce"
|
||||
version = "v1"
|
||||
|
||||
[[projects]]
|
||||
name = "gopkg.in/ini.v1"
|
||||
packages = ["."]
|
||||
revision = "6529cf7c58879c08d927016dde4477f18a0634cb"
|
||||
version = "v1.36.0"
|
||||
|
||||
[[projects]]
|
||||
name = "gopkg.in/macaron.v1"
|
||||
packages = ["."]
|
||||
revision = "c1be95e6d21e769e44e1ec33cec9da5837861c10"
|
||||
version = "v1.3.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "v2"
|
||||
name = "gopkg.in/mail.v2"
|
||||
packages = ["."]
|
||||
revision = "5bc5c8bb07bd8d2803831fbaf8cbd630fcde2c68"
|
||||
|
||||
[[projects]]
|
||||
name = "gopkg.in/redis.v2"
|
||||
packages = ["."]
|
||||
revision = "e6179049628164864e6e84e973cfb56335748dea"
|
||||
version = "v2.3.2"
|
||||
|
||||
[[projects]]
|
||||
name = "gopkg.in/yaml.v2"
|
||||
packages = ["."]
|
||||
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
|
||||
version = "v2.2.1"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "6e9458f912a5f0eb3430b968f1b4dbc4e3b7671b282cf4fe1573419a6d9ba0d4"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
209
Gopkg.toml
Normal file
209
Gopkg.toml
Normal file
@@ -0,0 +1,209 @@
|
||||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
|
||||
ignored = [
|
||||
"github.com/grafana/grafana/data/*",
|
||||
"github.com/grafana/grafana/public/*",
|
||||
"github.com/grafana/grafana/node_modules/*"
|
||||
]
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/BurntSushi/toml"
|
||||
version = "0.3.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/Unknwon/com"
|
||||
#version = "1.0.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/aws/aws-sdk-go"
|
||||
version = "1.13.56"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/benbjohnson/clock"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/bmizerany/assert"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/codegangsta/cli"
|
||||
version = "1.20.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/davecgh/go-spew"
|
||||
version = "1.1.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/fatih/color"
|
||||
version = "1.5.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/go-ldap/ldap"
|
||||
version = "2.5.1"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/go-macaron/binding"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/go-macaron/gzip"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/go-macaron/session"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/go-sql-driver/mysql"
|
||||
revision = "2cc627ac8defc45d65066ae98f898166f580f9a4"
|
||||
#version = "1.3.0" //keeping this since we would rather depend on version then commit
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/go-stack/stack"
|
||||
version = "1.7.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/go-xorm/core"
|
||||
version = "=0.5.7"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/go-xorm/xorm"
|
||||
version = "=0.6.4"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/gorilla/websocket"
|
||||
version = "1.2.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/gosimple/slug"
|
||||
version = "1.1.1"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/grafana/grafana-plugin-model"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/hashicorp/go-hclog"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/hashicorp/go-plugin"
|
||||
revision = "e8d22c780116115ae5624720c9af0c97afe4f551"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/hashicorp/go-version"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/inconshreveable/log15"
|
||||
version = "2.13.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/lib/pq"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/mattn/go-isatty"
|
||||
version = "0.0.3"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/mattn/go-sqlite3"
|
||||
version = "1.7.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/opentracing/opentracing-go"
|
||||
version = "1.0.2"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/patrickmn/go-cache"
|
||||
version = "2.1.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/prometheus/client_golang"
|
||||
version = "0.9.0-pre1"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/prometheus/client_model"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/prometheus/common"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/smartystreets/goconvey"
|
||||
version = "1.6.3"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/uber/jaeger-client-go"
|
||||
version = "2.11.2"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/yudai/gojsondiff"
|
||||
version = "1.0.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/net"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/oauth2"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sync"
|
||||
|
||||
[[constraint]]
|
||||
name = "gopkg.in/mail.v2"
|
||||
branch = "v2"
|
||||
|
||||
[[constraint]]
|
||||
name = "gopkg.in/ini.v1"
|
||||
version = "1.32.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "gopkg.in/macaron.v1"
|
||||
version = "1.2.4"
|
||||
|
||||
[[constraint]]
|
||||
branch = "v2"
|
||||
name = "gopkg.in/yaml.v2"
|
||||
|
||||
[prune]
|
||||
non-go = true
|
||||
go-tests = true
|
||||
unused-packages = true
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/teris-io/shortid"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/denisenkom/go-mssqldb"
|
||||
revision = "270bc3860bb94dd3a3ffd047377d746c5e276726"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/VividCortex/mysqlerr"
|
||||
branch = "master"
|
||||
55
Gruntfile.js
Normal file
55
Gruntfile.js
Normal file
@@ -0,0 +1,55 @@
|
||||
'use strict';
|
||||
module.exports = function (grunt) {
|
||||
var os = require('os');
|
||||
var config = {
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
baseDir: '.',
|
||||
srcDir: 'public',
|
||||
genDir: 'public_gen',
|
||||
destDir: 'dist',
|
||||
tempDir: 'tmp',
|
||||
platform: process.platform.replace('win32', 'windows'),
|
||||
};
|
||||
|
||||
if (grunt.option('platform')) {
|
||||
config.platform = grunt.option('platform');
|
||||
}
|
||||
|
||||
if (grunt.option('arch')) {
|
||||
config.arch = grunt.option('arch');
|
||||
} else {
|
||||
config.arch = os.arch();
|
||||
|
||||
if (process.platform.match(/^win/)) {
|
||||
config.arch = process.env.hasOwnProperty('ProgramFiles(x86)') ? 'x64' : 'x86';
|
||||
}
|
||||
}
|
||||
|
||||
config.phjs = grunt.option('phjsToRelease');
|
||||
config.pkg.version = grunt.option('pkgVer') || config.pkg.version;
|
||||
|
||||
console.log('Version', config.pkg.version);
|
||||
|
||||
// load plugins
|
||||
require('load-grunt-tasks')(grunt);
|
||||
|
||||
// load task definitions
|
||||
grunt.loadTasks('./scripts/grunt');
|
||||
|
||||
// Utility function to load plugin settings into config
|
||||
function loadConfig(config,path) {
|
||||
require('glob').sync('*', {cwd: path}).forEach(function(option) {
|
||||
var key = option.replace(/\.js$/,'');
|
||||
// If key already exists, extend it. It is your responsibility to avoid naming collisions
|
||||
config[key] = config[key] || {};
|
||||
grunt.util._.extend(config[key], require(path + option)(config,grunt));
|
||||
});
|
||||
// technically not required
|
||||
return config;
|
||||
}
|
||||
|
||||
// Merge that object with what with whatever we have here
|
||||
loadConfig(config,'./scripts/grunt/options/');
|
||||
// pass the config to grunt
|
||||
grunt.initConfig(config);
|
||||
};
|
||||
348
ISSUE_TRIAGE.md
348
ISSUE_TRIAGE.md
@@ -1,348 +0,0 @@
|
||||
# Triage issues
|
||||
|
||||
The main goal of issue triage is to categorize all incoming Grafana issues and make sure each issue has all basic information needed for anyone else to understand and be able to start working on it.
|
||||
|
||||
> **Note:** This information is for Grafana project Maintainers, Owners, and Admins. If you are a Contributor, then you will not be able to perform most of the tasks in this topic.
|
||||
|
||||
The core maintainers of the Grafana project are responsible for categorizing all incoming issues and delegating any critical or important issue to other maintainers. Currently one maintainer each week is responsible. Besides that part, triage provides an important way to contribute to an open source project.
|
||||
|
||||
Triage helps ensure issues resolve quickly by:
|
||||
|
||||
- Ensuring the issue's intent and purpose is conveyed precisely. This is necessary because it can be difficult for an issue to explain how an end user experiences a problem and what actions they took.
|
||||
- Giving a contributor the information they need before they commit to resolving an issue.
|
||||
- Lowering the issue count by preventing duplicate issues.
|
||||
- Streamlining the development process by preventing duplicate discussions.
|
||||
|
||||
If you don't have the knowledge or time to code, consider helping with triage. The community will thank you for saving them time by spending some of yours.
|
||||
|
||||
## Simplified flowchart diagram of the issue triage process
|
||||
|
||||
<!-- https://textik.com/#610afa78553def29 -->
|
||||
```
|
||||
+--------------------------+
|
||||
+----------------+ New issue opened/ |
|
||||
| | more information added |
|
||||
| +-------------+------------+
|
||||
| Ask for more |
|
||||
| information +-------------+------------+
|
||||
| | All information needed |
|
||||
| +--------+ to categorize the issue? +--------+
|
||||
| | | | |
|
||||
| | NO +--------------------------+ YES |
|
||||
| | |
|
||||
+------+-------+-------------+ +------------+---------+ +----------------------------+
|
||||
| | | | | |
|
||||
| label: needs more info | | Needs investigation? +--YES---+ label: needs investigation |
|
||||
| | | | | |
|
||||
+----------------------------+ +----------------+-----+ +--------------+-------------+
|
||||
NO | |
|
||||
| Investigate |
|
||||
+-----------+----------+ |
|
||||
| label: type/* | |
|
||||
| label: area/* +------------------+
|
||||
| label: datasource/* |
|
||||
+-----|----------+-----+
|
||||
| |
|
||||
| |
|
||||
| +--+--------------------+ +--------------------+
|
||||
| | | | label: priority/* |
|
||||
| | Needs priority? +--YES---+| milestone? |
|
||||
| | | | |
|
||||
| +--------------------+--+ +----+---------------+
|
||||
| NO | |
|
||||
| | |
|
||||
+----+-------------+ +---+----------+ |
|
||||
| | | | |
|
||||
| Close issue +----------+ Done +------+
|
||||
| | | |
|
||||
+------------------+ +--------------+
|
||||
```
|
||||
|
||||
## 1. Find uncategorized issues
|
||||
|
||||
To get started with issue triage and finding issues that haven't been triaged you have two alternatives.
|
||||
|
||||
### Browse unlabeled issues
|
||||
|
||||
The easiest and straight forward way of getting started and finding issues that haven't been triaged is to browse [unlabeled issues](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+no%3Alabel) and starting from the bottom and working yourself to the top.
|
||||
|
||||
### Subscribe to all notifications
|
||||
|
||||
The more advanced, but recommended way is to subscribe to all notifications from this repository which means that all new issues, pull requests, comments and important status changes are sent to your configured email address. Read this [guide](https://help.github.com/en/articles/watching-and-unwatching-repositories#watching-a-single-repository) for help with setting this up.
|
||||
|
||||
It's highly recommended that you setup filters to automatically remove emails from the inbox and label/categorize them accordingly to make it easy for you to understand when you need to act upon a notification or where to look for finding issues that haven't been triaged etc.
|
||||
|
||||
Instructions for setting up filters in Gmail can be found [here](#setting-up-gmail-filters). Another alternative is to use [Trailer](https://github.com/ptsochantaris/trailer) or similar software.
|
||||
|
||||
## 2. Ensure the issue contains basic information
|
||||
|
||||
Before triaging an issue very far, make sure that the issue's author provided the standard issue information. This will help you make an educated recommendation on how to categorize the issue. The Grafana project utilizes [GitHub issue templates](https://help.github.com/en/articles/creating-issue-templates-for-your-repository) to guide contributors to provide standard information that must be included for each type of template or type of issue.
|
||||
|
||||
### Standard issue information that must be included
|
||||
|
||||
Given a certain [issue template]([template](https://github.com/grafana/grafana/issues/new/choose)) have been used by the issue author or depending how the issue is perceived by the issue triage responsible, the following should help you understand what standard issue information that must be included.
|
||||
|
||||
#### Bug reports
|
||||
|
||||
Should explain what happened, what was expected and how to reproduce it together with any additional information that may help giving a complete picture of what happened such as screenshots, [query inspector](https://community.grafana.com/t/using-grafanas-query-inspector-to-troubleshoot-issues/2630) output and any environment related information that's applicable and/or maybe related to the reported problem:
|
||||
- Grafana version
|
||||
- Data source type & version
|
||||
- Platform & OS Grafana is installed on
|
||||
- User OS & Browser + versions
|
||||
- Using docker + what environment
|
||||
- Which plugins
|
||||
- Configuration database in use (sqlite, mysql, postgres)
|
||||
- Reverse proxy in front of Grafana, what version and configuration
|
||||
- Non-default configuration settings
|
||||
- Development environment like Go and Node versions, if applicable
|
||||
|
||||
#### Enhancement requests
|
||||
|
||||
Should explain what enhancement or feature that the author wants to be added and why that is needed.
|
||||
|
||||
#### Accessibility issues
|
||||
|
||||
This is a mix between a bug report and enhancement request but focused on accessibility issues to help make Grafana improve keyboard navigation, screen-reader support and being accessible to everyone. The report should include relevant WCAG criteria, if applicable.
|
||||
|
||||
#### Support requests
|
||||
|
||||
In general, if the issue description and title is perceived as a question no more information is needed.
|
||||
|
||||
### Good practices
|
||||
|
||||
To make it easier for everyone to understand and find issues they're searching for it's suggested as a general rule of thumbs to:
|
||||
|
||||
- Make sure that issue titles are named to explain the subject of the issue, has a correct spelling and doesn't include irrelevant information and/or sensitive information.
|
||||
- Make sure that issue descriptions doesn't include irrelevant information, information from template that haven't been filled out and/or sensitive information.
|
||||
- Do your best effort to change title and description or request suggested changes by adding a comment.
|
||||
|
||||
> **Note:** Above rules is applicable to both new and existing issues of the Grafana project.
|
||||
|
||||
### Do you have all the information needed to categorize an issue?
|
||||
|
||||
Depending on the issue, you might not feel all this information is needed. Use your best judgement. If you cannot triage an issue using what its author provided, explain kindly to the author that they must provide the above information to clarify the problem. Label issue with `needs more detail` and add any related `area/*` or `datasource/*` labels.
|
||||
|
||||
If the author provides the standard information but you are still unable to triage the issue, request additional information. Do this kindly and politely because you are asking for more of the author's time.
|
||||
|
||||
If the author does not respond to the requested information within the timespan of a week, close the issue with a kind note stating that the author can request for the issue to be reopened when the necessary information is provided.
|
||||
|
||||
When you feel you have all the information needed you're ready to [categorizing the issue](#3-categorizing-an-issue).
|
||||
|
||||
If you receive a notification with additional information provided but you are not anymore on issue triage and you feel you do not have time to handle it, you should delegate it to the current person on issue triage.
|
||||
|
||||
## 3. Categorizing an issue
|
||||
|
||||
An issue can have multiple of the following labels. Typically, a properly categorized issue should at least have:
|
||||
|
||||
- One label identifying its type (`type/*`).
|
||||
- One or multiple labels identifying the functional areas of interest or component (`area/*`) and/or data source (`datasource/*`), if applicable.
|
||||
|
||||
| Label | Description |
|
||||
| ------------------------ | ------------------------------------------------------------------------- |
|
||||
| `type/bug` | A feature isn't working as expected given design or documentation. |
|
||||
| `type/feature-request` | Request for a new feature or enhancement. |
|
||||
| `type/docs` | Documentation problem or enhancement. |
|
||||
| `type/accessibility` | Accessibility problem or enhancement. |
|
||||
| `type/question` | Issue is a question or is perceived as such. |
|
||||
| `type/duplicate` | An existing issue of the same subject/request have already been reported. |
|
||||
| `type/works-as-intended` | A reported bug works as intended/by design. |
|
||||
| `type/build-packaging` | Build or packaging problem or enhancement. |
|
||||
| `area/*` | Subject is related to a functional area of interest or component. |
|
||||
| `datasource/*` | Subject is related to a core data source plugin. |
|
||||
|
||||
### Duplicate issues
|
||||
|
||||
Make sure it's not a duplicate by searching existing issues using related terms from the issue title and description. If you think you know there is an existing issue, but can't find it, please reach out to one of the maintainers and ask for help. If you identify that the issue is a duplicate of an existing issue:
|
||||
|
||||
1. Add a comment `/duplicate of #<issue number>`. GitHub will recognize this and add some additional context to the issue activity.
|
||||
2. The Grafana bot will do the rest, adding the correct label and closing comment
|
||||
3. Optionally add any related `area/*` or `datasource/*` labels.
|
||||
|
||||
### Bug reports
|
||||
|
||||
If it's not perfectly clear that it's an actual bug, quickly try to reproduce it.
|
||||
|
||||
**It's a bug/it can be reproduced:**
|
||||
|
||||
1. Add a comment describing detailed steps for how to reproduce it, if applicable.
|
||||
2. Label the issue `type/bug` and at least one `area/*` or `datasource/*` label.
|
||||
3. If you know that maintainers wont be able to put any resources into it for some time then label the issue with `help wanted` and optionally `beginner friendly` together with pointers on which code to update to fix the bug. This should signal to the community that we would appreciate any help we can get to resolve this.
|
||||
4. Move on to [prioritizing the issue](#4-prioritization-of-issues).
|
||||
|
||||
**It can't be reproduced:**
|
||||
1. Either [ask for more information](#2-ensure-the-issue-contains-basic-information) needed to investigate it more thoroughly.
|
||||
2. Either [delegate further investigations](#investigation-of-issues) to someone else.
|
||||
|
||||
**It works as intended/by design:**
|
||||
1. Kindly and politely add a comment explaining briefly why we think it works as intended and close the issue.
|
||||
2. Label the issue `type/works-as-intended`.
|
||||
|
||||
### Enhancement/feature?
|
||||
|
||||
1. Label the issue `type/feature-request` and at least one `area/*` or `datasource/*` label.
|
||||
2. Move on to [prioritizing the issue](#4-prioritization-of-issues).
|
||||
|
||||
### Documentation issue?
|
||||
|
||||
First, evaluate if the documentation makes sense to be included in the Grafana project:
|
||||
|
||||
- Is this something we want/can maintain as a project?
|
||||
- Is this referring to usage of some specific integration/tool and in that case is that a popular use case in combination with Grafana?
|
||||
- If unsure, kindly and politely add a comment explaining that we would need [upvotes](https://help.github.com/en/articles/about-conversations-on-github#reacting-to-ideas-in-comments) to identify that lots of other users want/need this.
|
||||
|
||||
Second, label the issue `type/docs` and at least one `area/*` or `datasource/*` label.
|
||||
|
||||
**Minor typo/error/lack of information:**
|
||||
|
||||
There's a minor typo/error/lack of information that adds a lot of confusion for users and given the amount of work is a big win to make sure fixing it:
|
||||
1. Either update the documentation yourself and open a pull request.
|
||||
2. Either delegate the work to someone else by assigning that person to the issue and add the issue to next major/minor milestone.
|
||||
|
||||
**Major error/lack of information:**
|
||||
|
||||
1. Label the issue with `help wanted` and `beginner friendly`, if applicable, to signal that we find this important to fix and we would appreciate any help we can get from the community.
|
||||
2. Move on to [prioritizing the issue](#4-prioritization-of-issues).
|
||||
|
||||
### Accessibility issues
|
||||
|
||||
1. Label the issue `type/accessibility` and at least one `area/*` or `datasource/*` label.
|
||||
|
||||
### Support requests
|
||||
|
||||
1. Kindly and politely direct the issue author to the [community site](https://community.grafana.com/) and explain that GitHub is mainly used for tracking bugs and feature requests. If possible, it's usually a good idea to add some pointers to the issue author's question.
|
||||
2. Close the issue and label it with `type/question`.
|
||||
|
||||
## 4. Prioritization of issues
|
||||
|
||||
In general bugs and enhancement issues should be labeled with a priority.
|
||||
|
||||
This is the most difficult thing with triaging issues since it requires a lot of knowledge, context and experience before being able to think of and start feel comfortable adding a certain priority label.
|
||||
|
||||
The key here is asking for help and discuss issues to understand how more experienced project members think and reason. By doing that you learn more and eventually be more and more comfortable with prioritizing issues.
|
||||
|
||||
In case there is an uncertainty around the prioritization of an issue, please ask the maintainers for help.
|
||||
|
||||
| Label | Description |
|
||||
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `priority/critical` | Highest priority. Must be actively worked on as someone's top priority right now. |
|
||||
| `priority/support-subscription` | This is important for one or several customers having a paid Grafana support subscription. |
|
||||
| `priority/important-soon` | Must be staffed and worked on either currently, or very soon, ideally in time for the next release. |
|
||||
| `priority/important-longterm` | Important over the long term, but may not be staffed and/or may need multiple releases to complete. |
|
||||
| `priority/nice-to-have` | It's a good idea, but not scheduled for any release. |
|
||||
| `priority/awaiting-more-evidence` | Lowest priority. Possibly useful, but not yet enough interest in it. |
|
||||
| `priority/unscheduled` | Something to look into before and to be discussed during the planning of the next (upcoming) major/minor stable release. |
|
||||
|
||||
**Critical bugs**
|
||||
|
||||
1. If a bug has been categorized and any of the following criteria apply, the bug should be labeled as critical and must be actively worked on as someone's top priority right now.
|
||||
|
||||
- Results in any data loss
|
||||
- Critical security or performance issues
|
||||
- Problem that makes a feature unusable
|
||||
- Multiple users experience a severe problem affecting their business, users etc.
|
||||
|
||||
2. Label the issue `priority/critical`.
|
||||
3. If applicable, label the issue `priority/support-subscription`.
|
||||
4. Add the issue to the next upcoming patch release milestone. Create a new milestone if there are none.
|
||||
5. Escalate the problem to the maintainers.
|
||||
6. Assign or ask a maintainer for help assigning someone to make this issue their top priority right now.
|
||||
|
||||
**Important short-term**
|
||||
|
||||
1. Label the issue `priority/important-soon`.
|
||||
2. If applicable, label the issue `priority/support-subscription`.
|
||||
3. Add the issue to the next upcoming patch or major/minor stable release milestone. Ask maintainers for help if unsure if it's a patch or not. Create a new milestone if there are none.
|
||||
4. Make sure to add the issue to a suitable backlog of a GitHub project and prioritize it or assign someone to work on it now or very soon.
|
||||
5. Consider requesting [help from the community](#5-requesting-help-from-the-community), even though it may be problematic given a short amount of time until it should be released.
|
||||
|
||||
**Important long-term**
|
||||
|
||||
1. Label the issue `priority/important-longterm`.
|
||||
2. Consider requesting [help from the community](#5-requesting-help-from-the-community).
|
||||
|
||||
**Nice to have**
|
||||
|
||||
1. Label the issue `priority/nice-to-have`.
|
||||
2. Consider requesting [help from the community](#5-requesting-help-from-the-community).
|
||||
|
||||
**Not critical, but unsure?**
|
||||
|
||||
1. Label the issue `priority/unscheduled`.
|
||||
2. Consider requesting [help from the community](#5-requesting-help-from-the-community).
|
||||
|
||||
## 5. Requesting help from the community
|
||||
|
||||
Depending on the issue and/or priority, it's always a good idea to consider signalling to the community that help from community is appreciated and needed in case an issue is not prioritized to be worked on by maintainers. Use your best judgement. In general, requesting help from the community means that a contribution has a good chance of getting accepted and merged.
|
||||
|
||||
In many cases the issue author or community as a whole is more suitable to contribute changes since they're experts in their domain. It's also quite common that someone has tried to get something to work using the documentation without success and made an effort to get it to work and/or reached out to the [community site](https://community.grafana.com/) to get the missing information. Particularly in these areas it's more likely that there exist experts in their own domain and it is usually a good idea to request help from contributors:
|
||||
|
||||
- Database setups
|
||||
- Authentication like OAuth providers and LDAP setups
|
||||
- Platform specific things
|
||||
- Reverse proxy setups
|
||||
- Alert notifiers
|
||||
|
||||
1. Kindly and politely add a comment to signal to users subscribed to updates of the issue.
|
||||
- Explain that the issue would be nice to get resolved, but it isn't prioritized to work on by maintainers for an unforeseen future.
|
||||
- If possible or applicable, try to help contributors getting starting by adding pointers and references to what code/files need to be changed and/or ideas of a good way to solve/implement the issue.
|
||||
2. Label the issue with `help wanted`.
|
||||
3. If applicable, label the issue with `beginner friendly` to denote that the issue is suitable for a beginner to work on.
|
||||
4. If possible, try to estimate the amount of work by adding `effort/small`, `effort/medium` or `effort/large`.
|
||||
|
||||
## Investigation of issues
|
||||
|
||||
When an issue has all basic information provided, but the triage responsible haven't been able to reproduce the reported problem at a first glance, the issue is labeled [Needs investigation](https://github.com/grafana/grafana/labels/needs%20investigation). Depending on the perceived severity and/or number of [upvotes](https://help.github.com/en/articles/about-conversations-on-github#reacting-to-ideas-in-comments), the investigation will either be delegated to another maintainer for further investigation or put on hold until someone else (maintainer or contributor) picks it up and eventually starts investigating it.
|
||||
|
||||
Investigating issues can be a very time consuming task, especially for the maintainers, given the huge number of combinations of plugins, data sources, platforms, databases, browsers, tools, hardware, integrations, versions and cloud services, etc that are being used with Grafana. There is a certain number of combinations that are more common than others, and these are in general easier for maintainers to investigate.
|
||||
|
||||
For some other combinations it may not be possible at all for a maintainer to setup a proper test environment to investigate the issue. In these cases we really appreciate any help we can get from the community. Otherwise the issue is highly likely to be closed.
|
||||
|
||||
Even if you don't have the time or knowledge to investigate an issue we highly recommend that you [upvote](https://help.github.com/en/articles/about-conversations-on-github#reacting-to-ideas-in-comments) the issue if you happen to have the same problem. If you have further details that may help investigating the issue please provide as much information as possible.
|
||||
|
||||
## Automation
|
||||
|
||||
We have some automation that triggers on comments or labels being added to issues. Many of these automated behaviors are defined in [commands.json](https://github.com/grafana/grafana/blob/main/.github/commands.json). Or in other [GitHub Actions](https://github.com/grafana/grafana/tree/main/.github/workflows)
|
||||
|
||||
* Add /duplicate `#<issue number>` to have Grafana label & close issue with an appropriate message.
|
||||
* Add `bot/question` and the bot will close it with an appropriate message.
|
||||
|
||||
[Read more on bot actions](https://github.com/grafana/grafana/blob/main/.github/bot.md)
|
||||
|
||||
## External PRs
|
||||
|
||||
Part of issue triage should also be triaging of external PRs. Main goal should be to make sure PRs from external contributors have an owner/reviewer and are not forgotten.
|
||||
|
||||
1. Check new external PRs which do not have a reviewer.
|
||||
1. Check if there is a link to an existing issue.
|
||||
1. If not and you know which issue it is solving, add the link yourself, otherwise ask the author to link the issue or create one.
|
||||
1. Assign a reviewer based on who was handling the linked issue or what code or feature does the PR touches (look at who was the last to make changes there if all else fails).
|
||||
|
||||
## Appendix
|
||||
|
||||
### Setting up Gmail filters
|
||||
|
||||
If you're using Gmail it's highly recommended that you setup filters to automatically remove email from the inbox and label them accordingly to make it easy for you to understand when you need to act upon a notification or process all incoming issues that haven't been triaged.
|
||||
|
||||
This may be setup by personal preference, but here's a working configuration for reference.
|
||||
1. Follow instructions in [gist](https://gist.github.com/marefr/9167c2e31466f6316c1cba118874e74f)
|
||||
2. In Gmail, go to Settings -> Filters and Blocked Addresses
|
||||
3. Import filters -> select xml file -> Open file
|
||||
4. Review filters
|
||||
5. Optional, Check Apply new filters to existing email
|
||||
6. Create filters
|
||||
|
||||
This will give you a structure of labels in the sidebar similar to the following:
|
||||
```
|
||||
- Inbox
|
||||
...
|
||||
- GitHub (mine)
|
||||
- activity
|
||||
- assigned
|
||||
- mentions
|
||||
- GitHub (other)
|
||||
- Grafana
|
||||
```
|
||||
|
||||
- All notifications you’ll need to read/take action on show up as unread in GitHub (mine) and its sub-labels.
|
||||
- All other notifications you don’t need to take action on show up as unread in GitHub (other) and its sub-labels
|
||||
- This is convenient for issue triage and to follow the activity in the Grafana project.
|
||||
661
LICENSE
661
LICENSE
@@ -1,661 +0,0 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
22
LICENSING.md
22
LICENSING.md
@@ -1,22 +0,0 @@
|
||||
# Licensing
|
||||
|
||||
License names used in this document are as per [SPDX License List](https://spdx.org/licenses/).
|
||||
|
||||
The default license for this project is [AGPL-3.0-only](LICENSE).
|
||||
|
||||
## Apache-2.0
|
||||
|
||||
The following folders and their subfolders are licensed under Apache-2.0:
|
||||
|
||||
```
|
||||
packages/grafana-data/
|
||||
packages/grafana-e2e/
|
||||
packages/grafana-e2e-selectors/
|
||||
packages/grafana-runtime/
|
||||
packages/grafana-toolkit/
|
||||
packages/grafana-ui/
|
||||
packages/jaeger-ui-components/
|
||||
packaging/
|
||||
grafana-mixin/
|
||||
cue/
|
||||
```
|
||||
@@ -1,8 +0,0 @@
|
||||
@torkelo is the main/default maintainer, some parts of the codebase have other maintainers:
|
||||
|
||||
- Backend:
|
||||
- @bergquist
|
||||
- Plugins:
|
||||
- @ryantxu
|
||||
- UX/UI:
|
||||
- @davkal
|
||||
151
Makefile
151
Makefile
@@ -1,152 +1,45 @@
|
||||
## This is a self-documented Makefile. For usage information, run `make help`:
|
||||
##
|
||||
## For more information, refer to https://suva.sh/posts/well-documented-makefiles/
|
||||
|
||||
-include local/Makefile
|
||||
|
||||
.PHONY: all deps-go deps-js deps build-go build-server build-cli build-js build build-docker-dev build-docker-full lint-go golangci-lint test-go test-js test run run-frontend clean devenv devenv-down protobuf help
|
||||
|
||||
GO = GO111MODULE=on go
|
||||
GO_FILES ?= ./pkg/...
|
||||
SH_FILES ?= $(shell find ./scripts -name *.sh)
|
||||
|
||||
all: deps build
|
||||
|
||||
##@ Dependencies
|
||||
deps-go:
|
||||
go run build.go setup
|
||||
|
||||
deps-go: ## Install backend dependencies.
|
||||
$(GO) run build.go setup
|
||||
|
||||
deps-js: node_modules ## Install frontend dependencies.
|
||||
|
||||
deps: deps-js ## Install all dependencies.
|
||||
|
||||
node_modules: package.json yarn.lock ## Install node modules.
|
||||
@echo "install frontend dependencies"
|
||||
deps-js:
|
||||
yarn install --pure-lockfile --no-progress
|
||||
|
||||
##@ Building
|
||||
deps: deps-js
|
||||
|
||||
build-go: ## Build all Go binaries.
|
||||
@echo "build go files"
|
||||
$(GO) run build.go build
|
||||
build-go:
|
||||
go run build.go build
|
||||
|
||||
build-server: ## Build Grafana server.
|
||||
@echo "build server"
|
||||
$(GO) run build.go build-server
|
||||
build-server:
|
||||
go run build.go build-server
|
||||
|
||||
build-cli: ## Build Grafana CLI application.
|
||||
@echo "build in CI environment"
|
||||
$(GO) run build.go build-cli
|
||||
build-cli:
|
||||
go run build.go build-cli
|
||||
|
||||
build-js: ## Build frontend assets.
|
||||
@echo "build frontend"
|
||||
build-js:
|
||||
yarn run build
|
||||
yarn run plugins:build-bundled
|
||||
|
||||
build: build-go build-js ## Build backend and frontend.
|
||||
build: build-go build-js
|
||||
|
||||
scripts/go/bin/bra: scripts/go/go.mod
|
||||
@cd scripts/go; \
|
||||
$(GO) build -o ./bin/bra github.com/unknwon/bra
|
||||
|
||||
run: scripts/go/bin/bra ## Build and run web server on filesystem changes.
|
||||
@GO111MODULE=on scripts/go/bin/bra run
|
||||
|
||||
run-frontend: deps-js ## Fetch js dependencies and watch frontend for rebuild
|
||||
yarn start
|
||||
|
||||
##@ Testing
|
||||
|
||||
test-go: ## Run tests for backend.
|
||||
@echo "test backend"
|
||||
$(GO) test -v ./pkg/...
|
||||
|
||||
test-js: ## Run tests for frontend.
|
||||
@echo "test frontend"
|
||||
yarn test
|
||||
|
||||
test: test-go test-js ## Run all tests.
|
||||
|
||||
##@ Linting
|
||||
scripts/go/bin/golangci-lint: scripts/go/go.mod
|
||||
@cd scripts/go; \
|
||||
$(GO) build -o ./bin/golangci-lint github.com/golangci/golangci-lint/cmd/golangci-lint
|
||||
|
||||
golangci-lint: scripts/go/bin/golangci-lint
|
||||
@echo "lint via golangci-lint"
|
||||
@scripts/go/bin/golangci-lint run \
|
||||
--config ./scripts/go/configs/.golangci.toml \
|
||||
$(GO_FILES)
|
||||
|
||||
lint-go: golangci-lint # Run all code checks for backend.
|
||||
|
||||
# with disabled SC1071 we are ignored some TCL,Expect `/usr/bin/env expect` scripts
|
||||
shellcheck: $(SH_FILES) ## Run checks for shell scripts.
|
||||
@docker run --rm -v "$$PWD:/mnt" koalaman/shellcheck:stable \
|
||||
$(SH_FILES) -e SC1071 -e SC2162
|
||||
|
||||
##@ Docker
|
||||
|
||||
build-docker-dev: ## Build Docker image for development (fast).
|
||||
@echo "build development container"
|
||||
build-docker-dev:
|
||||
@echo "\033[92mInfo:\033[0m the frontend code is expected to be built already."
|
||||
$(GO) run build.go -goos linux -pkg-arch amd64 ${OPT} build pkg-archive latest
|
||||
go run build.go -goos linux -pkg-arch amd64 ${OPT} build package-only latest
|
||||
cp dist/grafana-latest.linux-x64.tar.gz packaging/docker
|
||||
cd packaging/docker && docker build --tag grafana/grafana:dev .
|
||||
|
||||
build-docker-full: ## Build Docker image for development.
|
||||
@echo "build docker container"
|
||||
build-docker-full:
|
||||
docker build --tag grafana/grafana:dev .
|
||||
|
||||
##@ Services
|
||||
test-go:
|
||||
go test -v ./pkg/...
|
||||
|
||||
# create docker-compose file with provided sources and start them
|
||||
# example: make devenv sources=postgres,openldap
|
||||
ifeq ($(sources),)
|
||||
devenv:
|
||||
@printf 'You have to define sources for this command \nexample: make devenv sources=postgres,openldap\n'
|
||||
else
|
||||
devenv: devenv-down ## Start optional services, e.g. postgres, prometheus, and elasticsearch.
|
||||
$(eval targets := $(shell echo '$(sources)' | tr "," " "))
|
||||
test-js:
|
||||
yarn test
|
||||
|
||||
@cd devenv; \
|
||||
./create_docker_compose.sh $(targets) || \
|
||||
(rm -rf {docker-compose.yaml,conf.tmp,.env}; exit 1)
|
||||
test: test-go test-js
|
||||
|
||||
@cd devenv; \
|
||||
docker-compose up -d --build
|
||||
endif
|
||||
|
||||
devenv-down: ## Stop optional services.
|
||||
@cd devenv; \
|
||||
test -f docker-compose.yaml && \
|
||||
docker-compose down || exit 0;
|
||||
|
||||
##@ Helpers
|
||||
|
||||
# We separate the protobuf generation because most development tasks on
|
||||
# Grafana do not involve changing protobuf files and protoc is not a
|
||||
# go-gettable dependency and so getting it installed can be inconvenient.
|
||||
#
|
||||
# If you are working on changes to protobuf interfaces you may either use
|
||||
# this target or run the individual scripts below directly.
|
||||
protobuf: ## Compile protobuf definitions
|
||||
bash scripts/protobuf-check.sh
|
||||
bash pkg/plugins/backendplugin/pluginextensionv2/generate.sh
|
||||
|
||||
clean: ## Clean up intermediate build artifacts.
|
||||
@echo "cleaning"
|
||||
rm -rf node_modules
|
||||
rm -rf public/build
|
||||
|
||||
# This repository's configuration is protected (https://readme.drone.io/signature/).
|
||||
# Use this make target to regenerate the configuration YAML files when
|
||||
# you modify starlark files.
|
||||
drone:
|
||||
drone starlark
|
||||
drone lint
|
||||
drone --server https://drone.grafana.net sign --save grafana/grafana
|
||||
|
||||
help: ## Display this help.
|
||||
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
|
||||
run:
|
||||
./bin/grafana-server
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
Copyright 2014-2021 Grafana Labs
|
||||
Copyright 2014-2018 Grafana Labs
|
||||
|
||||
This software is based on Kibana:
|
||||
Copyright 2012-2013 Elasticsearch BV
|
||||
|
||||
@@ -1,33 +1,29 @@
|
||||
# Plugin development
|
||||
# Plugin Development
|
||||
|
||||
This document is not meant as a complete guide for developing plugins but more as a changelog for changes in
|
||||
Grafana that can impact plugin development. Whenever you as a plugin author encounter an issue with your plugin after
|
||||
This document is not meant as complete guide for developing plugins but more as a changelog for changes in
|
||||
Grafana that can impact plugin development. When ever you as plugin author encounter an issue with your plugin after
|
||||
upgrading Grafana please check here before creating an issue.
|
||||
|
||||
## Plugin development resources
|
||||
## Links
|
||||
|
||||
- [Grafana plugin developer guide](http://docs.grafana.org/plugins/developing/development/)
|
||||
- [Datasource plugin written in typescript](https://github.com/grafana/typescript-template-datasource)
|
||||
- [Simple json dataource plugin](https://github.com/grafana/simple-json-datasource)
|
||||
- [Plugin development guide](http://docs.grafana.org/plugins/developing/development/)
|
||||
- [Webpack Grafana plugin template project](https://github.com/CorpGlory/grafana-plugin-template-webpack)
|
||||
- [Simple JSON datasource plugin](https://github.com/grafana/simple-json-datasource)
|
||||
|
||||
## Changes in Grafana v4.6
|
||||
## Changes in v4.6
|
||||
|
||||
This version of Grafana has big changes that will impact a limited set of plugins. We moved from systemjs to webpack
|
||||
for built-in plugins and everything internal. External plugins still use systemjs but now with a limited
|
||||
for built-in plugins & everything internal. External plugins still use systemjs but now with a limited
|
||||
set of Grafana components they can import. Plugins can depend on libs like lodash & moment and internal components
|
||||
like before using the same import paths. However since everything in Grafana is no longer accessible, a few plugins could encounter issues when importing a Grafana dependency.
|
||||
|
||||
[List of exposed components plugins can import/require](https://github.com/grafana/grafana/blob/main/public/app/features/plugins/plugin_loader.ts#L48)
|
||||
[List of exposed components plugins can import/require](https://github.com/grafana/grafana/blob/master/public/app/features/plugins/plugin_loader.ts#L48)
|
||||
|
||||
If you think we missed exposing a crucial lib or Grafana component let us know by opening an issue.
|
||||
|
||||
### Deprecated components
|
||||
|
||||
The angular directive `<spectrum-picker>` is now deprecated (will still work for a version more) but we recommend plugin authors
|
||||
upgrade to new `<color-picker color="ctrl.color" onChange="ctrl.onSparklineColorChange"></color-picker>`
|
||||
to upgrade to new `<color-picker color="ctrl.color" onChange="ctrl.onSparklineColorChange"></color-picker>`
|
||||
|
||||
## Changes in Grafana v6.0
|
||||
|
||||
### DashboardSrv.ts
|
||||
|
||||
If you utilize [DashboardSrv](https://github.com/grafana/grafana/commit/8574dca081002f36e482b572517d8f05fd44453f#diff-1ab99561f9f6a10e1fafcddc39bc1d65) in your plugin code, `dash` was renamed to `dashboard`.
|
||||
|
||||
155
README.md
155
README.md
@@ -1,47 +1,142 @@
|
||||

|
||||
[Grafana](https://grafana.com) [](https://circleci.com/gh/grafana/grafana) [](https://goreportcard.com/report/github.com/grafana/grafana) [](https://codecov.io/gh/grafana/grafana)
|
||||
================
|
||||
[Website](https://grafana.com) |
|
||||
[Twitter](https://twitter.com/grafana) |
|
||||
[Community & Forum](https://community.grafana.com)
|
||||
|
||||
The open-source platform for monitoring and observability.
|
||||
Grafana is an open source, feature rich metrics dashboard and graph editor for
|
||||
Graphite, Elasticsearch, OpenTSDB, Prometheus and InfluxDB.
|
||||
|
||||
[](LICENSE)
|
||||
[](https://drone.grafana.net/grafana/grafana)
|
||||
[](https://goreportcard.com/report/github.com/grafana/grafana)
|
||||

|
||||
|
||||
Grafana allows you to query, visualize, alert on and understand your metrics no matter where they are stored. Create, explore, and share dashboards with your team and foster a data driven culture:
|
||||
## Installation
|
||||
Head to [docs.grafana.org](http://docs.grafana.org/installation/) and [download](https://grafana.com/get)
|
||||
the latest release.
|
||||
|
||||
- **Visualize:** Fast and flexible client side graphs with a multitude of options. Panel plugins offer many different ways to visualize metrics and logs.
|
||||
- **Dynamic Dashboards:** Create dynamic & reusable dashboards with template variables that appear as dropdowns at the top of the dashboard.
|
||||
- **Explore Metrics:** Explore your data through ad-hoc queries and dynamic drilldown. Split view and compare different time ranges, queries and data sources side by side.
|
||||
- **Explore Logs:** Experience the magic of switching from metrics to logs with preserved label filters. Quickly search through all your logs or streaming them live.
|
||||
- **Alerting:** Visually define alert rules for your most important metrics. Grafana will continuously evaluate and send notifications to systems like Slack, PagerDuty, VictorOps, OpsGenie.
|
||||
- **Mixed Data Sources:** Mix different data sources in the same graph! You can specify a data source on a per-query basis. This works for even custom datasources.
|
||||
If you have any problems please read the [troubleshooting guide](http://docs.grafana.org/installation/troubleshooting/).
|
||||
|
||||
## Get started
|
||||
## Documentation & Support
|
||||
Be sure to read the [getting started guide](http://docs.grafana.org/guides/gettingstarted/) and the other feature guides.
|
||||
|
||||
- [Get Grafana](https://grafana.com/get)
|
||||
- [Installation guides](http://docs.grafana.org/installation/)
|
||||
## Run from master
|
||||
If you want to build a package yourself, or contribute - Here is a guide for how to do that. You can always find
|
||||
the latest master builds [here](https://grafana.com/grafana/download)
|
||||
|
||||
Unsure if Grafana is for you? Watch Grafana in action on [play.grafana.org](https://play.grafana.org/)!
|
||||
### Dependencies
|
||||
|
||||
## Documentation
|
||||
- Go 1.11
|
||||
- NodeJS LTS
|
||||
|
||||
The Grafana documentation is available at [grafana.com/docs](https://grafana.com/docs/).
|
||||
### Building the backend
|
||||
```bash
|
||||
go get github.com/grafana/grafana
|
||||
cd $GOPATH/src/github.com/grafana/grafana
|
||||
go run build.go setup
|
||||
go run build.go build
|
||||
```
|
||||
|
||||
## Contributing
|
||||
### Building frontend assets
|
||||
|
||||
If you're interested in contributing to the Grafana project:
|
||||
For this you need nodejs (v.6+).
|
||||
|
||||
- Start by reading the [Contributing guide](/CONTRIBUTING.md).
|
||||
- Learn how to set up your local environment, in our [Developer guide](/contribute/developer-guide.md).
|
||||
- Explore our [beginner-friendly issues](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3A%22beginner+friendly%22).
|
||||
- Look through our [style guide and Storybook](https://developers.grafana.com/ui/latest/index.html).
|
||||
To build the assets, rebuild on file change, and serve them by Grafana's webserver (http://localhost:3000):
|
||||
```bash
|
||||
npm install -g yarn
|
||||
yarn install --pure-lockfile
|
||||
yarn watch
|
||||
```
|
||||
|
||||
## Get involved
|
||||
Build the assets, rebuild on file change with Hot Module Replacement (HMR), and serve them by webpack-dev-server (http://localhost:3333):
|
||||
```bash
|
||||
yarn start
|
||||
# OR set a theme
|
||||
env GRAFANA_THEME=light yarn start
|
||||
```
|
||||
Note: HMR for Angular is not supported. If you edit files in the Angular part of the app, the whole page will reload.
|
||||
|
||||
- Follow [@grafana on Twitter](https://twitter.com/grafana/).
|
||||
- Read and subscribe to the [Grafana blog](https://grafana.com/blog/).
|
||||
- If you have a specific question, check out our [discussion forums](https://community.grafana.com/).
|
||||
- For general discussions, join us on the [official Slack](http://slack.raintank.io/) team.
|
||||
Run tests
|
||||
```bash
|
||||
yarn jest
|
||||
```
|
||||
|
||||
### Recompile backend on source change
|
||||
|
||||
To rebuild on source change.
|
||||
```bash
|
||||
go get github.com/Unknwon/bra
|
||||
bra run
|
||||
```
|
||||
|
||||
Open grafana in your browser (default: `http://localhost:3000`) and login with admin user (default: `user/pass = admin/admin`).
|
||||
|
||||
### Building a docker image (on linux/amd64)
|
||||
|
||||
This builds a docker image from your local sources:
|
||||
|
||||
1. Build the frontend `go run build.go build-frontend`
|
||||
2. Build the docker image `make build-docker-dev`
|
||||
|
||||
The resulting image will be tagged as `grafana/grafana:dev`
|
||||
|
||||
### Dev config
|
||||
|
||||
Create a custom.ini in the conf directory to override default configuration options.
|
||||
You only need to add the options you want to override. Config files are applied in the order of:
|
||||
|
||||
1. grafana.ini
|
||||
1. custom.ini
|
||||
|
||||
In your custom.ini uncomment (remove the leading `;`) sign. And set `app_mode = development`.
|
||||
|
||||
### Running tests
|
||||
|
||||
#### Frontend
|
||||
Execute all frontend tests
|
||||
```bash
|
||||
yarn test
|
||||
```
|
||||
|
||||
Writing & watching frontend tests
|
||||
|
||||
- Start watcher: `yarn jest`
|
||||
- Jest will run all test files that end with the name ".test.ts"
|
||||
|
||||
#### Backend
|
||||
```bash
|
||||
# Run Golang tests using sqlite3 as database (default)
|
||||
go test ./pkg/...
|
||||
|
||||
# Run Golang tests using mysql as database - convenient to use /docker/blocks/mysql_tests
|
||||
GRAFANA_TEST_DB=mysql go test ./pkg/...
|
||||
|
||||
# Run Golang tests using postgres as database - convenient to use /docker/blocks/postgres_tests
|
||||
GRAFANA_TEST_DB=postgres go test ./pkg/...
|
||||
```
|
||||
|
||||
## Building custom docker image
|
||||
|
||||
You can build a custom image using Docker, which doesn't require installing any dependencies besides docker itself.
|
||||
```bash
|
||||
git clone https://github.com/grafana/grafana
|
||||
cd grafana
|
||||
docker build -t grafana:dev .
|
||||
docker run -d --name=grafana -p 3000:3000 grafana:dev
|
||||
```
|
||||
|
||||
Open grafana in your browser (default: `http://localhost:3000`) and login with admin user (default: `user/pass = admin/admin`).
|
||||
|
||||
## Contribute
|
||||
|
||||
If you have any idea for an improvement or found a bug, do not hesitate to open an issue.
|
||||
And if you have time clone this repo and submit a pull request and help me make Grafana
|
||||
the kickass metrics & devops dashboard we all dream about!
|
||||
|
||||
## Plugin development
|
||||
|
||||
Checkout the [Plugin Development Guide](http://docs.grafana.org/plugins/developing/development/) and checkout the [PLUGIN_DEV.md](https://github.com/grafana/grafana/blob/master/PLUGIN_DEV.md) file for changes in Grafana that relate to
|
||||
plugin development.
|
||||
|
||||
## License
|
||||
|
||||
Grafana is distributed under [AGPL-3.0-only](LICENSE). For Apache-2.0 exceptions, see [LICENSING.md](LICENSING.md).
|
||||
Grafana is distributed under Apache 2.0 License.
|
||||
|
||||
|
||||
29
ROADMAP.md
29
ROADMAP.md
@@ -1,5 +1,28 @@
|
||||
# Roadmap
|
||||
# Roadmap (2018-08-07)
|
||||
|
||||
The roadmap is a tentative plan for the core development team. Things change constantly as pull requests come in and priorities change, but it will give you an idea of our current vision and plan.
|
||||
This roadmap is a tentative plan for the core development team. Things change constantly as PRs come in and priorities change.
|
||||
But it will give you an idea of our current vision and plan.
|
||||
|
||||
To view the Roadmap, go to the Issues tab on GitHub. There you will find three roadmap issues pinned at the top.
|
||||
### Short term (1-2 months)
|
||||
- PRs & Bugs
|
||||
- Multi-Stat panel
|
||||
- Metrics & Log Explore UI
|
||||
|
||||
### Mid term (2-4 months)
|
||||
- React Panels
|
||||
- Change visualization (panel type) on the fly.
|
||||
- Templating Query Editor UI Plugin hook
|
||||
- Backend plugins
|
||||
|
||||
### Long term (4 - 8 months)
|
||||
- Alerting improvements (silence, per series tracking, etc)
|
||||
- Progress on React migration
|
||||
|
||||
### In a distant future far far away
|
||||
- Meta queries
|
||||
- Integrated light weight TSDB
|
||||
- Web socket & live data sources
|
||||
|
||||
### Outside contributions
|
||||
We know this is being worked on right now by contributors (and we hope to merge it when it's ready).
|
||||
|
||||
|
||||
20
SECURITY.md
20
SECURITY.md
@@ -1,20 +0,0 @@
|
||||
# Reporting security issues
|
||||
|
||||
If you think you have found a security vulnerability, please send a report to [security@grafana.com](mailto:security@grafana.com). This address can be used for all of Grafana Labs's open source and commercial products (including but not limited to Grafana, Grafana Cloud, Grafana Enterprise, and grafana.com). We can accept only vulnerability reports at this address.
|
||||
|
||||
Please encrypt your message to us; please use our PGP key. The key fingerprint is:
|
||||
|
||||
F988 7BEA 027A 049F AE8E 5CAA D125 8932 BE24 C5CA
|
||||
|
||||
The key is available from [keyserver.ubuntu.com](https://keyserver.ubuntu.com/pks/lookup?search=0xF9887BEA027A049FAE8E5CAAD1258932BE24C5CA&fingerprint=on&op=index).
|
||||
|
||||
Grafana Labs will send you a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
|
||||
|
||||
**Important:** We ask you to not disclose the vulnerability before it have been fixed and announced, unless you received a response from the Grafana Labs security team that you can do so.
|
||||
|
||||
## Security announcements
|
||||
|
||||
We maintain a category on the community site called [Security Announcements](https://community.grafana.com/c/security-announcements),
|
||||
where we will post a summary, remediation, and mitigation details for any patch containing security fixes.
|
||||
|
||||
You can also subscribe to email updates to this category if you have a grafana.com account and sign on to the community site or track updates via an [RSS feed](https://community.grafana.com/c/security-announcements.rss).
|
||||
10
SUPPORT.md
10
SUPPORT.md
@@ -1,10 +0,0 @@
|
||||
# Get Grafana help
|
||||
------------------
|
||||
First, check the official [Grafana documentation](https://grafana.com/docs/).
|
||||
|
||||
If you require further help or support then ask a question in the [Grafana community site](https://community.grafana.com/) or [Grafana Slack](http://slack.raintank.io/). You can also search the community site for previously answered questions, in case someone already had your problem and got help.
|
||||
|
||||
**Please note:**
|
||||
- The Grafana project uses GitHub mainly for tracking bugs and feature requests.
|
||||
- Do not open an issue just to ask a question. The issue will be closed immediately.
|
||||
- Only submit issues for bug reports, feature requests, or enhancements.
|
||||
@@ -1,108 +0,0 @@
|
||||
# Guide to upgrading dependencies
|
||||
|
||||
Upgrading Go or Node.js requires making changes in many different files. See below for a list and explanation for each.
|
||||
|
||||
## Go
|
||||
|
||||
- CircleCi
|
||||
- `grafana/build-container`
|
||||
- Appveyor
|
||||
- Dockerfile
|
||||
|
||||
## Node.js
|
||||
|
||||
- CircleCI
|
||||
- `grafana/build-container`
|
||||
- Appveyor
|
||||
- Dockerfile
|
||||
|
||||
## Go dependencies
|
||||
|
||||
The Grafana project uses [Go modules](https://golang.org/cmd/go/#hdr-Modules__module_versions__and_more) to manage dependencies on external packages. This requires a working Go environment with version 1.11 or greater installed.
|
||||
|
||||
> **Note:** Since most developers of Grafana still use the `GOPATH` we need to specify `GO111MODULE=on` to make `go mod` and `got get` work as intended. If you have setup Grafana outside of the `GOPATH` on your machine you can skip `GO111MODULE=on` when running the commands below.
|
||||
|
||||
To add or update a new dependency, use the `go get` command:
|
||||
|
||||
```bash
|
||||
# The GO111MODULE variable can be omitted when the code isn't located in GOPATH.
|
||||
# Pick the latest tagged release.
|
||||
GO111MODULE=on go get example.com/some/module/pkg
|
||||
|
||||
# Pick a specific version.
|
||||
GO111MODULE=on go get example.com/some/module/pkg@vX.Y.Z
|
||||
```
|
||||
|
||||
Tidy up the `go.mod` and `go.sum` files:
|
||||
|
||||
```bash
|
||||
# The GO111MODULE variable can be omitted when the code isn't located in GOPATH.
|
||||
GO111MODULE=on go mod tidy
|
||||
```
|
||||
|
||||
You have to commit the changes to `go.mod` and `go.sum` before submitting the pull request.
|
||||
|
||||
## Node.js dependencies
|
||||
|
||||
Updated using `yarn`.
|
||||
|
||||
- `package.json`
|
||||
|
||||
## Where to make changes
|
||||
|
||||
### CircleCI
|
||||
|
||||
Our builds run on CircleCI through our build script.
|
||||
|
||||
#### Files
|
||||
|
||||
- `.circleci/config.yml`.
|
||||
|
||||
#### Dependencies
|
||||
|
||||
- nodejs
|
||||
- golang
|
||||
- grafana/build-container (our custom docker build container)
|
||||
|
||||
### grafana/build-container
|
||||
|
||||
The main build step (in CircleCI) is built using a custom build container that comes pre-baked with some of the necessary dependencies.
|
||||
|
||||
Link: [grafana/build-container](https://github.com/grafana/grafana/tree/main/scripts/build/ci-build)
|
||||
|
||||
#### Dependencies
|
||||
|
||||
- fpm
|
||||
- nodejs
|
||||
- golang
|
||||
- crosscompiling (several compilers)
|
||||
|
||||
### Appveyor
|
||||
|
||||
Main and release builds trigger test runs on Appveyors build environment so that tests will run on Windows.
|
||||
|
||||
#### Files:
|
||||
|
||||
- `appveyor.yml`
|
||||
|
||||
#### Dependencies
|
||||
|
||||
- nodejs
|
||||
- golang
|
||||
|
||||
### Dockerfile
|
||||
|
||||
There is a Docker build for Grafana in the root of the project that allows anyone to build Grafana just using Docker.
|
||||
|
||||
#### Files
|
||||
|
||||
- `Dockerfile`
|
||||
|
||||
#### Dependencies
|
||||
|
||||
- nodejs
|
||||
- golang
|
||||
|
||||
### Local developer environments
|
||||
|
||||
Please send out a notice in the grafana-dev slack channel when updating Go or Node.js to make it easier for everyone to update their local developer environments.
|
||||
77
WORKFLOW.md
77
WORKFLOW.md
@@ -1,77 +0,0 @@
|
||||
# Grafana workflow
|
||||
|
||||
This document is based on [GOVERNANCE.md](GOVERNANCE.md). We assume good faith and intend to keep all processes as lightweight as possible but as specific as required. In case of disagreements about anything in this document, GOVERNANCE.md applies.
|
||||
|
||||
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in [RFC2119](http://tools.ietf.org/html/rfc2119).
|
||||
|
||||
Git and [GitHub terminology](https://help.github.com/en/github/getting-started-with-github/github-glossary) are used throughout this document.
|
||||
|
||||
Team members and their access to repositories is maintained through [GitHub teams](https://help.github.com/en/github/setting-up-and-managing-organizations-and-teams/about-teams). Team maintainers add and remove team members as outlined in GOVERNANCE.md.
|
||||
|
||||
# Code changes
|
||||
|
||||
## Proposing changes
|
||||
|
||||
Examples of proposed changes are overarching architecture, component design, and specific code or graphical elements. Proposed changes SHOULD cover the big picture and intention, but individual parts SHOULD be split into the smallest possible changes. Changes SHOULD be based on and target the main branch. Depending on size of the proposed change, each change SHOULD be discussed, in increasing order of change size and complexity:
|
||||
- Directly in a RR (Pull Request) - this MAY be done, but SHOULD not be the common case.
|
||||
- Issue
|
||||
- Developer mailing list
|
||||
- Design document, shared via Google Docs, accessible to at least all team members.
|
||||
|
||||
Significant changes MUST be discussed and agreed upon with the relevant subsystem maintainers.
|
||||
|
||||
## Merging PRs (Pull Requests)
|
||||
|
||||
Depending on the size and complexity of a PR, different requirements MUST be applied. Any team member contributing substantially to a PR MUST NOT count against review requirements.
|
||||
Commits MUST be merged into main using PRs. They MUST NOT be merged into main directly.
|
||||
- Every merge MUST be approved by at least one team member.
|
||||
- Non-trivial changes MUST be approved by at least
|
||||
- two team members, or
|
||||
- one subsystem maintainer.
|
||||
- Significant changes MUST be approved by at least
|
||||
- two team members, AND
|
||||
- the relevant subsystem maintainer.
|
||||
|
||||
PRs MUST be [reviewed](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/reviewing-changes-in-pull-requests) and [approved](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/approving-a-pull-request-with-required-reviews) via GitHub’s review system.
|
||||
- Reviewers MAY write comments if approving
|
||||
- Reviewers MUST write comments if rejecting a PR or if requesting changes.
|
||||
|
||||
Once a PR is approved as per above, any team member MAY merge the PR.
|
||||
|
||||
## Backporting a PR
|
||||
|
||||
PRs intended for inclusion in the next PATCH release they must be backported to the release branch. The bot can do this automatically. [Read more on backport PRs](https://github.com/grafana/grafana/blob/main/.github/bot.md). Both the source PR and the backport PR should be assigned to the patch release milestone, unless you are backporting to many releases then it can differ.
|
||||
|
||||
Backport PRs are also needed during the beta period to get fixes into the stable release.
|
||||
|
||||
# Release workflow
|
||||
|
||||
## Branch structure
|
||||
|
||||
Grafana uses trunk-based development.
|
||||
|
||||
In particular, we found that the following principles match how we work:
|
||||
- Main and release branches MUST always build without failure.
|
||||
- Branches SHOULD be merged often. Larger changes SHOULD be activated with feature flags until they are ready. Long-lived development branches SHOULD be avoided.
|
||||
- Changes MAY be enabled by default once they are in a complete state
|
||||
- Changes which span multiple PRs MUST be described in an overarching issue or Google Doc.
|
||||
|
||||
## Releases
|
||||
|
||||
Releases MUST follow [Semantic Versioning](https://semver.org/) in naming and SHOULD follow Semantic Versioning as closely as reasonably possible for non-library software.
|
||||
|
||||
Release branches MUST be split from the following branches.
|
||||
- MAJOR release branches MUST be based on main.
|
||||
- MINOR release branches MUST be based on main.
|
||||
- PATCH release branches MUST be split from the relevant MINOR release branch’s most current PATCH
|
||||
|
||||
Security releases follow the same process but MUST be prepared in secret. Security releases MUST NOT include changes which are not related to the security fix. Normal release processes MUST accommodate the security release process. SECURITY.md MUST be followed.
|
||||
|
||||
Releases follow the following cadence
|
||||
- MAJOR: Yearly
|
||||
- MINOR: Every 4-6 weeks
|
||||
- PATCH: As needed
|
||||
|
||||
Releases SHOULD NOT be delayed by pending changes.
|
||||
|
||||
Releases MUST be coordinated with the relevant subsystem maintainers.
|
||||
@@ -1,38 +0,0 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
|
||||
"mainEntryPointFilePath": "<projectFolder>/dist/index.d.ts",
|
||||
"bundledPackages": [],
|
||||
"compiler": {},
|
||||
"apiReport": {
|
||||
"enabled": false
|
||||
},
|
||||
"docModel": {
|
||||
"enabled": true,
|
||||
"apiJsonFilePath": "<projectFolder>/../../reports/docs/<unscopedPackageName>.api.json"
|
||||
},
|
||||
"dtsRollup": {
|
||||
"enabled": false
|
||||
},
|
||||
"tsdocMetadata": {},
|
||||
"messages": {
|
||||
"compilerMessageReporting": {
|
||||
"default": {
|
||||
"logLevel": "warning"
|
||||
}
|
||||
},
|
||||
"extractorMessageReporting": {
|
||||
"default": {
|
||||
"logLevel": "warning"
|
||||
},
|
||||
"ae-internal-missing-underscore": {
|
||||
"logLevel": "none",
|
||||
"addToApiReportFile": false
|
||||
}
|
||||
},
|
||||
"tsdocMessageReporting": {
|
||||
"default": {
|
||||
"logLevel": "warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
40
appveyor.yml
Normal file
40
appveyor.yml
Normal file
@@ -0,0 +1,40 @@
|
||||
version: "{build}"
|
||||
|
||||
os: Windows Server 2012 R2
|
||||
|
||||
clone_folder: c:\gopath\src\github.com\grafana\grafana
|
||||
|
||||
environment:
|
||||
nodejs_version: "6"
|
||||
GOPATH: C:\gopath
|
||||
GOVERSION: 1.11
|
||||
|
||||
install:
|
||||
- rmdir c:\go /s /q
|
||||
# install nodejs and npm
|
||||
- ps: Install-Product node $env:nodejs_version
|
||||
- npm install -g yarn --silent
|
||||
- yarn install --pure-lockfile --no-progress
|
||||
- npm install -g grunt-cli
|
||||
- appveyor DownloadFile https://storage.googleapis.com/golang/go%GOVERSION%.windows-amd64.zip
|
||||
- 7z x go%GOVERSION%.windows-amd64.zip -y -oC:\ > NUL
|
||||
# install gcc (needed for sqlite3)
|
||||
- choco install -y --limit-output mingw
|
||||
- set PATH=C:\tools\mingw64\bin;%PATH%
|
||||
- echo %PATH%
|
||||
- echo %GOPATH%
|
||||
- go version
|
||||
- go env
|
||||
# - go run build.go setup
|
||||
|
||||
build_script:
|
||||
- go run build.go build
|
||||
- grunt release
|
||||
- go run build.go sha-dist
|
||||
- cp dist/* .
|
||||
- go test -v ./pkg/...
|
||||
|
||||
artifacts:
|
||||
- path: grafana-*windows-*.*
|
||||
name: binzip
|
||||
type: zip
|
||||
379
build.go
379
build.go
@@ -9,7 +9,6 @@ import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/build"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
@@ -30,72 +29,50 @@ const (
|
||||
|
||||
var (
|
||||
//versionRe = regexp.MustCompile(`-[0-9]{1,3}-g[0-9a-f]{5,10}`)
|
||||
goarch string
|
||||
goos string
|
||||
gocc string
|
||||
cgo bool
|
||||
libc string
|
||||
pkgArch string
|
||||
version string = "v1"
|
||||
buildTags []string
|
||||
goarch string
|
||||
goos string
|
||||
gocc string
|
||||
cgo bool
|
||||
pkgArch string
|
||||
version string = "v1"
|
||||
// deb & rpm does not support semver so have to handle their version a little differently
|
||||
linuxPackageVersion string = "v1"
|
||||
linuxPackageIteration string = ""
|
||||
race bool
|
||||
phjsToRelease string
|
||||
workingDir string
|
||||
includeBuildId bool = true
|
||||
buildId string = "0"
|
||||
serverBinary string = "grafana-server"
|
||||
cliBinary string = "grafana-cli"
|
||||
binaries []string = []string{serverBinary, cliBinary}
|
||||
includeBuildNumber bool = true
|
||||
buildNumber int = 0
|
||||
binaries []string = []string{"grafana-server", "grafana-cli"}
|
||||
isDev bool = false
|
||||
enterprise bool = false
|
||||
skipRpmGen bool = false
|
||||
skipDebGen bool = false
|
||||
printGenVersion bool = false
|
||||
)
|
||||
|
||||
func main() {
|
||||
log.SetOutput(os.Stdout)
|
||||
log.SetFlags(0)
|
||||
|
||||
var buildIdRaw string
|
||||
var buildTagsRaw string
|
||||
ensureGoPath()
|
||||
|
||||
flag.StringVar(&goarch, "goarch", runtime.GOARCH, "GOARCH")
|
||||
flag.StringVar(&goos, "goos", runtime.GOOS, "GOOS")
|
||||
flag.StringVar(&gocc, "cc", "", "CC")
|
||||
flag.StringVar(&libc, "libc", "", "LIBC")
|
||||
flag.StringVar(&buildTagsRaw, "build-tags", "", "Sets custom build tags")
|
||||
flag.BoolVar(&cgo, "cgo-enabled", cgo, "Enable cgo")
|
||||
flag.StringVar(&pkgArch, "pkg-arch", "", "PKG ARCH")
|
||||
flag.StringVar(&phjsToRelease, "phjs", "", "PhantomJS binary")
|
||||
flag.BoolVar(&race, "race", race, "Use race detector")
|
||||
flag.BoolVar(&includeBuildId, "includeBuildId", includeBuildId, "IncludeBuildId in package name")
|
||||
flag.BoolVar(&includeBuildNumber, "includeBuildNumber", includeBuildNumber, "IncludeBuildNumber in package name")
|
||||
flag.BoolVar(&enterprise, "enterprise", enterprise, "Build enterprise version of Grafana")
|
||||
flag.StringVar(&buildIdRaw, "buildId", "0", "Build ID from CI system")
|
||||
flag.IntVar(&buildNumber, "buildNumber", 0, "Build number from CI system")
|
||||
flag.BoolVar(&isDev, "dev", isDev, "optimal for development, skips certain steps")
|
||||
flag.BoolVar(&skipRpmGen, "skipRpm", skipRpmGen, "skip rpm package generation (default: false)")
|
||||
flag.BoolVar(&skipDebGen, "skipDeb", skipDebGen, "skip deb package generation (default: false)")
|
||||
flag.BoolVar(&printGenVersion, "gen-version", printGenVersion, "generate Grafana version and output (default: false)")
|
||||
flag.Parse()
|
||||
|
||||
buildId = shortenBuildId(buildIdRaw)
|
||||
|
||||
readVersionFromPackageJson()
|
||||
|
||||
if pkgArch == "" {
|
||||
pkgArch = goarch
|
||||
}
|
||||
|
||||
if printGenVersion {
|
||||
printGeneratedVersion()
|
||||
return
|
||||
}
|
||||
|
||||
if len(buildTagsRaw) > 0 {
|
||||
buildTags = strings.Split(buildTagsRaw, ",")
|
||||
}
|
||||
|
||||
log.Printf("Version: %s, Linux Version: %s, Package Iteration: %s\n", version, linuxPackageVersion, linuxPackageIteration)
|
||||
|
||||
if flag.NArg() == 0 {
|
||||
@@ -110,22 +87,51 @@ func main() {
|
||||
case "setup":
|
||||
setup()
|
||||
|
||||
case "build-srv", "build-server":
|
||||
case "build-srv":
|
||||
clean()
|
||||
doBuild("grafana-server", "./pkg/cmd/grafana-server", buildTags)
|
||||
build("grafana-server", "./pkg/cmd/grafana-server", []string{})
|
||||
|
||||
case "build-cli":
|
||||
clean()
|
||||
doBuild("grafana-cli", "./pkg/cmd/grafana-cli", buildTags)
|
||||
build("grafana-cli", "./pkg/cmd/grafana-cli", []string{})
|
||||
|
||||
case "build-server":
|
||||
clean()
|
||||
build("grafana-server", "./pkg/cmd/grafana-server", []string{})
|
||||
|
||||
case "build":
|
||||
//clean()
|
||||
for _, binary := range binaries {
|
||||
doBuild(binary, "./pkg/cmd/"+binary, buildTags)
|
||||
build(binary, "./pkg/cmd/"+binary, []string{})
|
||||
}
|
||||
|
||||
case "build-frontend":
|
||||
yarn("build")
|
||||
grunt(gruntBuildArg("build")...)
|
||||
|
||||
case "test":
|
||||
test("./pkg/...")
|
||||
grunt("test")
|
||||
|
||||
case "package":
|
||||
grunt(gruntBuildArg("build")...)
|
||||
grunt(gruntBuildArg("package")...)
|
||||
if goos == linux {
|
||||
createLinuxPackages()
|
||||
}
|
||||
|
||||
case "package-only":
|
||||
grunt(gruntBuildArg("package")...)
|
||||
if goos == linux {
|
||||
createLinuxPackages()
|
||||
}
|
||||
|
||||
case "pkg-rpm":
|
||||
grunt(gruntBuildArg("release")...)
|
||||
createRpmPackages()
|
||||
|
||||
case "pkg-deb":
|
||||
grunt(gruntBuildArg("release")...)
|
||||
createDebPackages()
|
||||
|
||||
case "sha-dist":
|
||||
shaFilesInDist()
|
||||
@@ -149,15 +155,9 @@ func makeLatestDistCopies() {
|
||||
}
|
||||
|
||||
latestMapping := map[string]string{
|
||||
"_amd64.deb": "dist/grafana_latest_amd64.deb",
|
||||
".x86_64.rpm": "dist/grafana-latest-1.x86_64.rpm",
|
||||
".linux-amd64.tar.gz": "dist/grafana-latest.linux-x64.tar.gz",
|
||||
".linux-amd64-musl.tar.gz": "dist/grafana-latest.linux-x64-musl.tar.gz",
|
||||
".linux-armv7.tar.gz": "dist/grafana-latest.linux-armv7.tar.gz",
|
||||
".linux-armv7-musl.tar.gz": "dist/grafana-latest.linux-armv7-musl.tar.gz",
|
||||
".linux-armv6.tar.gz": "dist/grafana-latest.linux-armv6.tar.gz",
|
||||
".linux-arm64.tar.gz": "dist/grafana-latest.linux-arm64.tar.gz",
|
||||
".linux-arm64-musl.tar.gz": "dist/grafana-latest.linux-arm64-musl.tar.gz",
|
||||
"_amd64.deb": "dist/grafana_latest_amd64.deb",
|
||||
".x86_64.rpm": "dist/grafana-latest-1.x86_64.rpm",
|
||||
".linux-amd64.tar.gz": "dist/grafana-latest.linux-x64.tar.gz",
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
@@ -197,58 +197,231 @@ func readVersionFromPackageJson() {
|
||||
}
|
||||
|
||||
// add timestamp to iteration
|
||||
if includeBuildId {
|
||||
if buildId != "0" {
|
||||
linuxPackageIteration = fmt.Sprintf("%s%s", buildId, linuxPackageIteration)
|
||||
if includeBuildNumber {
|
||||
if buildNumber != 0 {
|
||||
linuxPackageIteration = fmt.Sprintf("%d%s", buildNumber, linuxPackageIteration)
|
||||
} else {
|
||||
linuxPackageIteration = fmt.Sprintf("%d%s", time.Now().Unix(), linuxPackageIteration)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func yarn(params ...string) {
|
||||
runPrint(`yarn run`, params...)
|
||||
type linuxPackageOptions struct {
|
||||
packageType string
|
||||
homeDir string
|
||||
binPath string
|
||||
serverBinPath string
|
||||
cliBinPath string
|
||||
configDir string
|
||||
ldapFilePath string
|
||||
etcDefaultPath string
|
||||
etcDefaultFilePath string
|
||||
initdScriptFilePath string
|
||||
systemdServiceFilePath string
|
||||
|
||||
postinstSrc string
|
||||
initdScriptSrc string
|
||||
defaultFileSrc string
|
||||
systemdFileSrc string
|
||||
|
||||
depends []string
|
||||
}
|
||||
|
||||
func genPackageVersion() string {
|
||||
if includeBuildId {
|
||||
return fmt.Sprintf("%v-%v", linuxPackageVersion, linuxPackageIteration)
|
||||
} else {
|
||||
return version
|
||||
func createDebPackages() {
|
||||
previousPkgArch := pkgArch
|
||||
if pkgArch == "armv7" {
|
||||
pkgArch = "armhf"
|
||||
}
|
||||
createPackage(linuxPackageOptions{
|
||||
packageType: "deb",
|
||||
homeDir: "/usr/share/grafana",
|
||||
binPath: "/usr/sbin",
|
||||
configDir: "/etc/grafana",
|
||||
etcDefaultPath: "/etc/default",
|
||||
etcDefaultFilePath: "/etc/default/grafana-server",
|
||||
initdScriptFilePath: "/etc/init.d/grafana-server",
|
||||
systemdServiceFilePath: "/usr/lib/systemd/system/grafana-server.service",
|
||||
|
||||
postinstSrc: "packaging/deb/control/postinst",
|
||||
initdScriptSrc: "packaging/deb/init.d/grafana-server",
|
||||
defaultFileSrc: "packaging/deb/default/grafana-server",
|
||||
systemdFileSrc: "packaging/deb/systemd/grafana-server.service",
|
||||
|
||||
depends: []string{"adduser", "libfontconfig"},
|
||||
})
|
||||
pkgArch = previousPkgArch
|
||||
}
|
||||
|
||||
func createRpmPackages() {
|
||||
previousPkgArch := pkgArch
|
||||
switch {
|
||||
case pkgArch == "armv7":
|
||||
pkgArch = "armhfp"
|
||||
case pkgArch == "arm64":
|
||||
pkgArch = "aarch64"
|
||||
}
|
||||
createPackage(linuxPackageOptions{
|
||||
packageType: "rpm",
|
||||
homeDir: "/usr/share/grafana",
|
||||
binPath: "/usr/sbin",
|
||||
configDir: "/etc/grafana",
|
||||
etcDefaultPath: "/etc/sysconfig",
|
||||
etcDefaultFilePath: "/etc/sysconfig/grafana-server",
|
||||
initdScriptFilePath: "/etc/init.d/grafana-server",
|
||||
systemdServiceFilePath: "/usr/lib/systemd/system/grafana-server.service",
|
||||
|
||||
postinstSrc: "packaging/rpm/control/postinst",
|
||||
initdScriptSrc: "packaging/rpm/init.d/grafana-server",
|
||||
defaultFileSrc: "packaging/rpm/sysconfig/grafana-server",
|
||||
systemdFileSrc: "packaging/rpm/systemd/grafana-server.service",
|
||||
|
||||
depends: []string{"/sbin/service", "fontconfig", "freetype", "urw-fonts"},
|
||||
})
|
||||
pkgArch = previousPkgArch
|
||||
}
|
||||
|
||||
func createLinuxPackages() {
|
||||
createDebPackages()
|
||||
createRpmPackages()
|
||||
}
|
||||
|
||||
func createPackage(options linuxPackageOptions) {
|
||||
packageRoot, _ := ioutil.TempDir("", "grafana-linux-pack")
|
||||
|
||||
// create directories
|
||||
runPrint("mkdir", "-p", filepath.Join(packageRoot, options.homeDir))
|
||||
runPrint("mkdir", "-p", filepath.Join(packageRoot, options.configDir))
|
||||
runPrint("mkdir", "-p", filepath.Join(packageRoot, "/etc/init.d"))
|
||||
runPrint("mkdir", "-p", filepath.Join(packageRoot, options.etcDefaultPath))
|
||||
runPrint("mkdir", "-p", filepath.Join(packageRoot, "/usr/lib/systemd/system"))
|
||||
runPrint("mkdir", "-p", filepath.Join(packageRoot, "/usr/sbin"))
|
||||
|
||||
// copy binary
|
||||
for _, binary := range binaries {
|
||||
runPrint("cp", "-p", filepath.Join(workingDir, "tmp/bin/"+binary), filepath.Join(packageRoot, "/usr/sbin/"+binary))
|
||||
}
|
||||
// copy init.d script
|
||||
runPrint("cp", "-p", options.initdScriptSrc, filepath.Join(packageRoot, options.initdScriptFilePath))
|
||||
// copy environment var file
|
||||
runPrint("cp", "-p", options.defaultFileSrc, filepath.Join(packageRoot, options.etcDefaultFilePath))
|
||||
// copy systemd file
|
||||
runPrint("cp", "-p", options.systemdFileSrc, filepath.Join(packageRoot, options.systemdServiceFilePath))
|
||||
// copy release files
|
||||
runPrint("cp", "-a", filepath.Join(workingDir, "tmp")+"/.", filepath.Join(packageRoot, options.homeDir))
|
||||
// remove bin path
|
||||
runPrint("rm", "-rf", filepath.Join(packageRoot, options.homeDir, "bin"))
|
||||
|
||||
args := []string{
|
||||
"-s", "dir",
|
||||
"--description", "Grafana",
|
||||
"-C", packageRoot,
|
||||
"--url", "https://grafana.com",
|
||||
"--maintainer", "contact@grafana.com",
|
||||
"--config-files", options.initdScriptFilePath,
|
||||
"--config-files", options.etcDefaultFilePath,
|
||||
"--config-files", options.systemdServiceFilePath,
|
||||
"--after-install", options.postinstSrc,
|
||||
|
||||
"--version", linuxPackageVersion,
|
||||
"-p", "./dist",
|
||||
}
|
||||
|
||||
name := "grafana"
|
||||
if enterprise {
|
||||
name += "-enterprise"
|
||||
args = append(args, "--replaces", "grafana")
|
||||
}
|
||||
args = append(args, "--name", name)
|
||||
|
||||
description := "Grafana"
|
||||
if enterprise {
|
||||
description += " Enterprise"
|
||||
}
|
||||
args = append(args, "--vendor", description)
|
||||
|
||||
if !enterprise {
|
||||
args = append(args, "--license", "\"Apache 2.0\"")
|
||||
}
|
||||
|
||||
if options.packageType == "rpm" {
|
||||
args = append(args, "--rpm-posttrans", "packaging/rpm/control/posttrans")
|
||||
}
|
||||
|
||||
if options.packageType == "deb" {
|
||||
args = append(args, "--deb-no-default-config-files")
|
||||
}
|
||||
|
||||
if pkgArch != "" {
|
||||
args = append(args, "-a", pkgArch)
|
||||
}
|
||||
|
||||
if linuxPackageIteration != "" {
|
||||
args = append(args, "--iteration", linuxPackageIteration)
|
||||
}
|
||||
|
||||
// add dependenciesj
|
||||
for _, dep := range options.depends {
|
||||
args = append(args, "--depends", dep)
|
||||
}
|
||||
|
||||
args = append(args, ".")
|
||||
|
||||
fmt.Println("Creating package: ", options.packageType)
|
||||
runPrint("fpm", append([]string{"-t", options.packageType}, args...)...)
|
||||
}
|
||||
|
||||
func ensureGoPath() {
|
||||
if os.Getenv("GOPATH") == "" {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
gopath := filepath.Clean(filepath.Join(cwd, "../../../../"))
|
||||
log.Println("GOPATH is", gopath)
|
||||
os.Setenv("GOPATH", gopath)
|
||||
}
|
||||
}
|
||||
|
||||
func grunt(params ...string) {
|
||||
if runtime.GOOS == windows {
|
||||
runPrint(`.\node_modules\.bin\grunt`, params...)
|
||||
} else {
|
||||
runPrint("./node_modules/.bin/grunt", params...)
|
||||
}
|
||||
}
|
||||
|
||||
func gruntBuildArg(task string) []string {
|
||||
args := []string{task}
|
||||
if includeBuildNumber {
|
||||
args = append(args, fmt.Sprintf("--pkgVer=%v-%v", linuxPackageVersion, linuxPackageIteration))
|
||||
} else {
|
||||
args = append(args, fmt.Sprintf("--pkgVer=%v", version))
|
||||
}
|
||||
if pkgArch != "" {
|
||||
args = append(args, fmt.Sprintf("--arch=%v", pkgArch))
|
||||
}
|
||||
if phjsToRelease != "" {
|
||||
args = append(args, fmt.Sprintf("--phjsToRelease=%v", phjsToRelease))
|
||||
}
|
||||
args = append(args, fmt.Sprintf("--platform=%v", goos))
|
||||
|
||||
return args
|
||||
}
|
||||
|
||||
func setup() {
|
||||
args := []string{"install", "-v"}
|
||||
if goos == windows {
|
||||
args = append(args, "-buildmode=exe")
|
||||
}
|
||||
args = append(args, "./pkg/cmd/grafana-server")
|
||||
runPrint("go", args...)
|
||||
}
|
||||
|
||||
func printGeneratedVersion() {
|
||||
fmt.Print(genPackageVersion())
|
||||
runPrint("go", "get", "-v", "github.com/golang/dep")
|
||||
runPrint("go", "install", "-v", "./pkg/cmd/grafana-server")
|
||||
}
|
||||
|
||||
func test(pkg string) {
|
||||
setBuildEnv()
|
||||
args := []string{"test", "-short", "-timeout", "60s"}
|
||||
if goos == windows {
|
||||
args = append(args, "-buildmode=exe")
|
||||
}
|
||||
args = append(args, pkg)
|
||||
runPrint("go", args...)
|
||||
runPrint("go", "test", "-short", "-timeout", "60s", pkg)
|
||||
}
|
||||
|
||||
func doBuild(binaryName, pkg string, tags []string) {
|
||||
libcPart := ""
|
||||
if libc != "" {
|
||||
libcPart = fmt.Sprintf("-%s", libc)
|
||||
}
|
||||
binary := fmt.Sprintf("./bin/%s-%s%s/%s", goos, goarch, libcPart, binaryName)
|
||||
func build(binaryName, pkg string, tags []string) {
|
||||
binary := fmt.Sprintf("./bin/%s-%s/%s", goos, goarch, binaryName)
|
||||
if isDev {
|
||||
//don't include os/arch/libc in output path in dev environment
|
||||
//don't include os and arch in output path in dev environment
|
||||
binary = fmt.Sprintf("./bin/%s", binaryName)
|
||||
}
|
||||
|
||||
@@ -260,10 +433,6 @@ func doBuild(binaryName, pkg string, tags []string) {
|
||||
rmr(binary, binary+".md5")
|
||||
}
|
||||
args := []string{"build", "-ldflags", ldflags()}
|
||||
if goos == windows {
|
||||
// Work around a linking error on Windows: "export ordinal too large"
|
||||
args = append(args, "-buildmode=exe")
|
||||
}
|
||||
if len(tags) > 0 {
|
||||
args = append(args, "-tags", strings.Join(tags, ","))
|
||||
}
|
||||
@@ -277,11 +446,7 @@ func doBuild(binaryName, pkg string, tags []string) {
|
||||
if !isDev {
|
||||
setBuildEnv()
|
||||
runPrint("go", "version")
|
||||
libcPart := ""
|
||||
if libc != "" {
|
||||
libcPart = fmt.Sprintf("/%s", libc)
|
||||
}
|
||||
fmt.Printf("Targeting %s/%s%s\n", goos, goarch, libcPart)
|
||||
fmt.Printf("Targeting %s/%s\n", goos, goarch)
|
||||
}
|
||||
|
||||
runPrint("go", args...)
|
||||
@@ -302,10 +467,6 @@ func ldflags() string {
|
||||
b.WriteString(fmt.Sprintf(" -X main.version=%s", version))
|
||||
b.WriteString(fmt.Sprintf(" -X main.commit=%s", getGitSha()))
|
||||
b.WriteString(fmt.Sprintf(" -X main.buildstamp=%d", buildStamp()))
|
||||
b.WriteString(fmt.Sprintf(" -X main.buildBranch=%s", getGitBranch()))
|
||||
if v := os.Getenv("LDFLAGS"); v != "" {
|
||||
b.WriteString(fmt.Sprintf(" -extldflags \"%s\"", v))
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
@@ -323,7 +484,7 @@ func clean() {
|
||||
|
||||
rmr("dist")
|
||||
rmr("tmp")
|
||||
rmr(filepath.Join(build.Default.GOPATH, fmt.Sprintf("pkg/%s_%s/github.com/grafana", goos, goarch)))
|
||||
rmr(filepath.Join(os.Getenv("GOPATH"), fmt.Sprintf("pkg/%s_%s/github.com/grafana", goos, goarch)))
|
||||
}
|
||||
|
||||
func setBuildEnv() {
|
||||
@@ -353,14 +514,6 @@ func setBuildEnv() {
|
||||
}
|
||||
}
|
||||
|
||||
func getGitBranch() string {
|
||||
v, err := runError("git", "rev-parse", "--abbrev-ref", "HEAD")
|
||||
if err != nil {
|
||||
return "main"
|
||||
}
|
||||
return string(v)
|
||||
}
|
||||
|
||||
func getGitSha() string {
|
||||
v, err := runError("git", "rev-parse", "--short", "HEAD")
|
||||
if err != nil {
|
||||
@@ -370,11 +523,6 @@ func getGitSha() string {
|
||||
}
|
||||
|
||||
func buildStamp() int64 {
|
||||
// use SOURCE_DATE_EPOCH if set.
|
||||
if s, _ := strconv.ParseInt(os.Getenv("SOURCE_DATE_EPOCH"), 10, 64); s > 0 {
|
||||
return s
|
||||
}
|
||||
|
||||
bs, err := runError("git", "show", "-s", "--format=%ct")
|
||||
if err != nil {
|
||||
return time.Now().Unix()
|
||||
@@ -396,7 +544,6 @@ func runError(cmd string, args ...string) ([]byte, error) {
|
||||
func runPrint(cmd string, args ...string) {
|
||||
log.Println(cmd, strings.Join(args, " "))
|
||||
ecmd := exec.Command(cmd, args...)
|
||||
ecmd.Env = append(os.Environ(), "GO111MODULE=on")
|
||||
ecmd.Stdout = os.Stdout
|
||||
ecmd.Stderr = os.Stderr
|
||||
err := ecmd.Run()
|
||||
@@ -472,11 +619,3 @@ func shaFile(file string) error {
|
||||
|
||||
return out.Close()
|
||||
}
|
||||
|
||||
func shortenBuildId(buildId string) string {
|
||||
buildId = strings.Replace(buildId, "-", "", -1)
|
||||
if len(buildId) < 9 {
|
||||
return buildId
|
||||
}
|
||||
return buildId[0:8]
|
||||
}
|
||||
|
||||
@@ -28,13 +28,13 @@ provisioning = conf/provisioning
|
||||
|
||||
#################################### Server ##############################
|
||||
[server]
|
||||
# Protocol (http, https, h2, socket)
|
||||
# Protocol (http, https, socket)
|
||||
protocol = http
|
||||
|
||||
# The ip address to bind to, empty will bind to all interfaces
|
||||
http_addr =
|
||||
|
||||
# The http port to use
|
||||
# The http port to use
|
||||
http_port = 3000
|
||||
|
||||
# The public facing domain name used to access grafana from a browser
|
||||
@@ -47,9 +47,6 @@ enforce_domain = false
|
||||
# The full public facing url
|
||||
root_url = %(protocol)s://%(domain)s:%(http_port)s/
|
||||
|
||||
# Serve Grafana from subpath specified in `root_url` setting. By default it is set to `false` for compatibility reasons.
|
||||
serve_from_sub_path = false
|
||||
|
||||
# Log web requests
|
||||
router_logging = false
|
||||
|
||||
@@ -66,13 +63,6 @@ cert_key =
|
||||
# Unix socket path
|
||||
socket = /tmp/grafana.sock
|
||||
|
||||
# CDN Url
|
||||
cdn_url =
|
||||
|
||||
# Sets the maximum time in minutes before timing out read of an incoming request and closing idle connections.
|
||||
# `0` means there is no timeout for reading the request.
|
||||
read_timeout = 0
|
||||
|
||||
#################################### Database ############################
|
||||
[database]
|
||||
# You can configure the database connection by specifying type, host, name, user and password
|
||||
@@ -105,12 +95,6 @@ log_queries =
|
||||
# For "mysql", use either "true", "false", or "skip-verify".
|
||||
ssl_mode = disable
|
||||
|
||||
# Database drivers may support different transaction isolation levels.
|
||||
# Currently, only "mysql" driver supports isolation levels.
|
||||
# If the value is empty - driver's default isolation level is applied.
|
||||
# For "mysql" use "READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ" or "SERIALIZABLE".
|
||||
isolation_level =
|
||||
|
||||
ca_cert_path =
|
||||
client_key_path =
|
||||
client_cert_path =
|
||||
@@ -119,19 +103,36 @@ server_cert_name =
|
||||
# For "sqlite3" only, path relative to data_path setting
|
||||
path = grafana.db
|
||||
|
||||
# For "sqlite3" only. cache mode setting used for connecting to the database
|
||||
cache_mode = private
|
||||
#################################### Session #############################
|
||||
[session]
|
||||
# Either "memory", "file", "redis", "mysql", "postgres", "memcache", default is "file"
|
||||
provider = file
|
||||
|
||||
#################################### Cache server #############################
|
||||
[remote_cache]
|
||||
# Either "redis", "memcached" or "database" default is "database"
|
||||
type = database
|
||||
|
||||
# cache connectionstring options
|
||||
# database: will use Grafana primary database.
|
||||
# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=0,ssl=false`. Only addr is required. ssl may be 'true', 'false', or 'insecure'.
|
||||
# Provider config options
|
||||
# memory: not have any config yet
|
||||
# file: session dir path, is relative to grafana data_path
|
||||
# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=grafana`
|
||||
# postgres: user=a password=b host=localhost port=5432 dbname=c sslmode=disable
|
||||
# mysql: go-sql-driver/mysql dsn config string, examples:
|
||||
# `user:password@tcp(127.0.0.1:3306)/database_name`
|
||||
# `user:password@unix(/var/run/mysqld/mysqld.sock)/database_name`
|
||||
# memcache: 127.0.0.1:11211
|
||||
connstr =
|
||||
|
||||
|
||||
provider_config = sessions
|
||||
|
||||
# Session cookie name
|
||||
cookie_name = grafana_sess
|
||||
|
||||
# If you use session in https only, default is false
|
||||
cookie_secure = false
|
||||
|
||||
# Session life time, default is 86400
|
||||
session_life_time = 86400
|
||||
gc_interval_time = 86400
|
||||
|
||||
# Connection Max Lifetime default is 14400 (means 14400 seconds or 4 hours)
|
||||
conn_max_lifetime = 14400
|
||||
|
||||
#################################### Data proxy ###########################
|
||||
[dataproxy]
|
||||
@@ -139,42 +140,6 @@ connstr =
|
||||
# This enables data proxy logging, default is false
|
||||
logging = false
|
||||
|
||||
# How long the data proxy waits to read the headers of the response before timing out, default is 30 seconds.
|
||||
# This setting also applies to core backend HTTP data sources where query requests use an HTTP client with timeout set.
|
||||
timeout = 30
|
||||
|
||||
# How long the data proxy waits to establish a TCP connection before timing out, default is 10 seconds.
|
||||
dialTimeout = 10
|
||||
|
||||
# How many seconds the data proxy waits before sending a keepalive request.
|
||||
keep_alive_seconds = 30
|
||||
|
||||
# How many seconds the data proxy waits for a successful TLS Handshake before timing out.
|
||||
tls_handshake_timeout_seconds = 10
|
||||
|
||||
# How many seconds the data proxy will wait for a server's first response headers after
|
||||
# fully writing the request headers if the request has an "Expect: 100-continue"
|
||||
# header. A value of 0 will result in the body being sent immediately, without
|
||||
# waiting for the server to approve.
|
||||
expect_continue_timeout_seconds = 1
|
||||
|
||||
# Optionally limits the total number of connections per host, including connections in the dialing,
|
||||
# active, and idle states. On limit violation, dials will block.
|
||||
# A value of zero (0) means no limit.
|
||||
max_conns_per_host = 0
|
||||
|
||||
# The maximum number of idle connections that Grafana will keep alive.
|
||||
max_idle_connections = 100
|
||||
|
||||
# The maximum number of idle connections per host that Grafana will keep alive.
|
||||
max_idle_connections_per_host = 2
|
||||
|
||||
# How many seconds the data proxy keeps an idle connection open before timing out.
|
||||
idle_conn_timeout_seconds = 90
|
||||
|
||||
# If enabled and user is not anonymous, data proxy will add X-Grafana-User header with username into the request.
|
||||
send_user_header = false
|
||||
|
||||
#################################### Analytics ###########################
|
||||
[analytics]
|
||||
# Server reporting, sends usage counters to stats.grafana.org every 24 hours.
|
||||
@@ -183,9 +148,6 @@ send_user_header = false
|
||||
# Change this option to false to disable reporting.
|
||||
reporting_enabled = true
|
||||
|
||||
# The name of the distributor of the Grafana instance. Ex hosted-grafana, grafana-labs
|
||||
reporting_distributor = grafana-labs
|
||||
|
||||
# Set to false to disable all checks to https://grafana.com
|
||||
# for new versions (grafana itself and plugins), check is used
|
||||
# in some UI views to notify that grafana or plugin update exists
|
||||
@@ -201,18 +163,20 @@ google_tag_manager_id =
|
||||
|
||||
#################################### Security ############################
|
||||
[security]
|
||||
# disable creation of admin user on first start of grafana
|
||||
disable_initial_admin_creation = false
|
||||
|
||||
# default admin user, created on startup
|
||||
admin_user = admin
|
||||
|
||||
# default admin password, can be changed before first start of grafana, or in profile settings
|
||||
# default admin password, can be changed before first start of grafana, or in profile settings
|
||||
admin_password = admin
|
||||
|
||||
# used for signing
|
||||
secret_key = SW2YcwTIb9zpOOhoPsMm
|
||||
|
||||
# Auto-login remember days
|
||||
login_remember_days = 7
|
||||
cookie_username = grafana_user
|
||||
cookie_remember_name = grafana_remember
|
||||
|
||||
# disable gravatar profile images
|
||||
disable_gravatar = false
|
||||
|
||||
@@ -222,47 +186,6 @@ data_source_proxy_whitelist =
|
||||
# disable protection against brute force login attempts
|
||||
disable_brute_force_login_protection = false
|
||||
|
||||
# set to true if you host Grafana behind HTTPS. default is false.
|
||||
cookie_secure = false
|
||||
|
||||
# set cookie SameSite attribute. defaults to `lax`. can be set to "lax", "strict", "none" and "disabled"
|
||||
cookie_samesite = lax
|
||||
|
||||
# set to true if you want to allow browsers to render Grafana in a <frame>, <iframe>, <embed> or <object>. default is false.
|
||||
allow_embedding = false
|
||||
|
||||
# Set to true if you want to enable http strict transport security (HSTS) response header.
|
||||
# This is only sent when HTTPS is enabled in this configuration.
|
||||
# HSTS tells browsers that the site should only be accessed using HTTPS.
|
||||
strict_transport_security = false
|
||||
|
||||
# Sets how long a browser should cache HSTS. Only applied if strict_transport_security is enabled.
|
||||
strict_transport_security_max_age_seconds = 86400
|
||||
|
||||
# Set to true if to enable HSTS preloading option. Only applied if strict_transport_security is enabled.
|
||||
strict_transport_security_preload = false
|
||||
|
||||
# Set to true if to enable the HSTS includeSubDomains option. Only applied if strict_transport_security is enabled.
|
||||
strict_transport_security_subdomains = false
|
||||
|
||||
# Set to true to enable the X-Content-Type-Options response header.
|
||||
# The X-Content-Type-Options response HTTP header is a marker used by the server to indicate that the MIME types advertised
|
||||
# in the Content-Type headers should not be changed and be followed.
|
||||
x_content_type_options = true
|
||||
|
||||
# Set to true to enable the X-XSS-Protection header, which tells browsers to stop pages from loading
|
||||
# when they detect reflected cross-site scripting (XSS) attacks.
|
||||
x_xss_protection = true
|
||||
|
||||
# Enable adding the Content-Security-Policy header to your requests.
|
||||
# CSP allows to control resources the user agent is allowed to load and helps prevent XSS attacks.
|
||||
content_security_policy = false
|
||||
|
||||
# Set Content Security Policy template used when adding the Content-Security-Policy header to your requests.
|
||||
# $NONCE in the template includes a random nonce.
|
||||
# $ROOT_PATH is server.root_url without the protocol.
|
||||
content_security_policy_template = """script-src 'self' 'unsafe-eval' 'unsafe-inline' 'strict-dynamic' $NONCE;object-src 'none';font-src 'self';style-src 'self' 'unsafe-inline' blob:;img-src * data:;base-uri 'self';connect-src 'self' grafana.com ws://$ROOT_PATH wss://$ROOT_PATH;manifest-src 'self';media-src 'none';form-action 'self';"""
|
||||
|
||||
#################################### Snapshots ###########################
|
||||
[snapshots]
|
||||
# snapshot sharing options
|
||||
@@ -270,10 +193,6 @@ external_enabled = true
|
||||
external_snapshot_url = https://snapshots-origin.raintank.io
|
||||
external_snapshot_name = Publish to snapshot.raintank.io
|
||||
|
||||
# Set to true to enable this Grafana instance act as an external snapshot server and allow unauthenticated requests for
|
||||
# creating and deleting snapshots.
|
||||
public_mode = false
|
||||
|
||||
# remove expired snapshot
|
||||
snapshot_remove_expired = true
|
||||
|
||||
@@ -283,18 +202,6 @@ snapshot_remove_expired = true
|
||||
# Number dashboard versions to keep (per dashboard). Default: 20, Minimum: 1
|
||||
versions_to_keep = 20
|
||||
|
||||
# Minimum dashboard refresh interval. When set, this will restrict users to set the refresh interval of a dashboard lower than given interval. Per default this is 5 seconds.
|
||||
# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
|
||||
min_refresh_interval = 5s
|
||||
|
||||
# Path to the default home dashboard. If this value is empty, then Grafana uses StaticRootPath + "dashboards/home.json"
|
||||
default_home_dashboard_path =
|
||||
|
||||
################################### Data sources #########################
|
||||
[datasources]
|
||||
# Upper limit of data sources that Grafana will return. This limit is a temporary configuration and it will be deprecated when pagination will be introduced on the list data sources API.
|
||||
datasource_limit = 5000
|
||||
|
||||
#################################### Users ###############################
|
||||
[users]
|
||||
# disable user signup / registration
|
||||
@@ -317,14 +224,10 @@ verify_email_enabled = false
|
||||
|
||||
# Background text for the user field on the login page
|
||||
login_hint = email or username
|
||||
password_hint = password
|
||||
|
||||
# Default UI theme ("dark" or "light")
|
||||
default_theme = dark
|
||||
|
||||
# Path to a custom home page. Users are only redirected to this if the default home dashboard is used. It should match a frontend route and contain a leading slash.
|
||||
home_page =
|
||||
|
||||
# External user management
|
||||
external_manage_link_url =
|
||||
external_manage_link_name =
|
||||
@@ -333,50 +236,16 @@ external_manage_info =
|
||||
# Viewers can edit/inspect dashboard settings in the browser. But not save the dashboard.
|
||||
viewers_can_edit = false
|
||||
|
||||
# Editors can administrate dashboard, folders and teams they create
|
||||
editors_can_admin = false
|
||||
|
||||
# The duration in time a user invitation remains valid before expiring. This setting should be expressed as a duration. Examples: 6h (hours), 2d (days), 1w (week). Default is 24h (24 hours). The minimum supported duration is 15m (15 minutes).
|
||||
user_invite_max_lifetime_duration = 24h
|
||||
|
||||
# Enter a comma-separated list of usernames to hide them in the Grafana UI. These users are shown to Grafana admins and to themselves.
|
||||
hidden_users =
|
||||
|
||||
[auth]
|
||||
# Login cookie name
|
||||
login_cookie_name = grafana_session
|
||||
|
||||
# The maximum lifetime (duration) an authenticated user can be inactive before being required to login at next visit. Default is 7 days (7d). This setting should be expressed as a duration, e.g. 5m (minutes), 6h (hours), 10d (days), 2w (weeks), 1M (month). The lifetime resets at each successful token rotation (token_rotation_interval_minutes).
|
||||
login_maximum_inactive_lifetime_duration =
|
||||
|
||||
# The maximum lifetime (duration) an authenticated user can be logged in since login time before being required to login. Default is 30 days (30d). This setting should be expressed as a duration, e.g. 5m (minutes), 6h (hours), 10d (days), 2w (weeks), 1M (month).
|
||||
login_maximum_lifetime_duration =
|
||||
|
||||
# How often should auth tokens be rotated for authenticated users when being active. The default is each 10 minutes.
|
||||
token_rotation_interval_minutes = 10
|
||||
|
||||
# Set to true to disable (hide) the login form, useful if you use OAuth
|
||||
disable_login_form = false
|
||||
|
||||
# Set to true to disable the sign out link in the side menu. Useful if you use auth.proxy or auth.jwt.
|
||||
# Set to true to disable the signout link in the side menu. useful if you use auth.proxy
|
||||
disable_signout_menu = false
|
||||
|
||||
# URL to redirect the user to after sign out
|
||||
signout_redirect_url =
|
||||
|
||||
# Set to true to attempt login with OAuth automatically, skipping the login screen.
|
||||
# This setting is ignored if multiple OAuth providers are configured.
|
||||
oauth_auto_login = false
|
||||
|
||||
# OAuth state max age cookie duration in seconds. Defaults to 600 seconds.
|
||||
oauth_state_cookie_max_age = 600
|
||||
|
||||
# limit of api_key seconds to live before expiration
|
||||
api_key_max_seconds_to_live = -1
|
||||
|
||||
# Set to true to enable SigV4 authentication option for HTTP-based datasources
|
||||
sigv4_auth_enabled = false
|
||||
|
||||
#################################### Anonymous Auth ######################
|
||||
[auth.anonymous]
|
||||
# enable anonymous access
|
||||
@@ -388,20 +257,16 @@ org_name = Main Org.
|
||||
# specify role for unauthenticated users
|
||||
org_role = Viewer
|
||||
|
||||
# mask the Grafana version number for unauthenticated users
|
||||
hide_version = false
|
||||
|
||||
#################################### GitHub Auth #########################
|
||||
#################################### Github Auth #########################
|
||||
[auth.github]
|
||||
enabled = false
|
||||
allow_sign_up = true
|
||||
client_id = some_id
|
||||
client_secret =
|
||||
client_secret = some_secret
|
||||
scopes = user:email,read:org
|
||||
auth_url = https://github.com/login/oauth/authorize
|
||||
token_url = https://github.com/login/oauth/access_token
|
||||
api_url = https://api.github.com/user
|
||||
allowed_domains =
|
||||
team_ids =
|
||||
allowed_organizations =
|
||||
|
||||
@@ -410,12 +275,11 @@ allowed_organizations =
|
||||
enabled = false
|
||||
allow_sign_up = true
|
||||
client_id = some_id
|
||||
client_secret =
|
||||
client_secret = some_secret
|
||||
scopes = api
|
||||
auth_url = https://gitlab.com/oauth/authorize
|
||||
token_url = https://gitlab.com/oauth/token
|
||||
api_url = https://gitlab.com/api/v4
|
||||
allowed_domains =
|
||||
allowed_groups =
|
||||
|
||||
#################################### Google Auth #########################
|
||||
@@ -423,7 +287,7 @@ allowed_groups =
|
||||
enabled = false
|
||||
allow_sign_up = true
|
||||
client_id = some_client_id
|
||||
client_secret =
|
||||
client_secret = some_client_secret
|
||||
scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
|
||||
auth_url = https://accounts.google.com/o/oauth2/auth
|
||||
token_url = https://accounts.google.com/o/oauth2/token
|
||||
@@ -437,7 +301,7 @@ hosted_domain =
|
||||
enabled = false
|
||||
allow_sign_up = true
|
||||
client_id = some_id
|
||||
client_secret =
|
||||
client_secret = some_secret
|
||||
scopes = user:email
|
||||
allowed_organizations =
|
||||
|
||||
@@ -445,59 +309,22 @@ allowed_organizations =
|
||||
enabled = false
|
||||
allow_sign_up = true
|
||||
client_id = some_id
|
||||
client_secret =
|
||||
client_secret = some_secret
|
||||
scopes = user:email
|
||||
allowed_organizations =
|
||||
|
||||
#################################### Azure AD OAuth #######################
|
||||
[auth.azuread]
|
||||
name = Azure AD
|
||||
enabled = false
|
||||
allow_sign_up = true
|
||||
client_id = some_client_id
|
||||
client_secret =
|
||||
scopes = openid email profile
|
||||
auth_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize
|
||||
token_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
|
||||
allowed_domains =
|
||||
allowed_groups =
|
||||
|
||||
#################################### Okta OAuth #######################
|
||||
[auth.okta]
|
||||
name = Okta
|
||||
enabled = false
|
||||
allow_sign_up = true
|
||||
client_id = some_id
|
||||
client_secret =
|
||||
scopes = openid profile email groups
|
||||
auth_url = https://<tenant-id>.okta.com/oauth2/v1/authorize
|
||||
token_url = https://<tenant-id>.okta.com/oauth2/v1/token
|
||||
api_url = https://<tenant-id>.okta.com/oauth2/v1/userinfo
|
||||
allowed_domains =
|
||||
allowed_groups =
|
||||
role_attribute_path =
|
||||
role_attribute_strict = false
|
||||
|
||||
#################################### Generic OAuth #######################
|
||||
[auth.generic_oauth]
|
||||
name = OAuth
|
||||
enabled = false
|
||||
allow_sign_up = true
|
||||
client_id = some_id
|
||||
client_secret =
|
||||
client_secret = some_secret
|
||||
scopes = user:email
|
||||
empty_scopes = false
|
||||
email_attribute_name = email:primary
|
||||
email_attribute_path =
|
||||
login_attribute_path =
|
||||
name_attribute_path =
|
||||
role_attribute_path =
|
||||
role_attribute_strict = false
|
||||
id_token_attribute_name =
|
||||
auth_url =
|
||||
token_url =
|
||||
api_url =
|
||||
allowed_domains =
|
||||
team_ids =
|
||||
allowed_organizations =
|
||||
tls_skip_verify_insecure = false
|
||||
@@ -515,24 +342,8 @@ enabled = false
|
||||
header_name = X-WEBAUTH-USER
|
||||
header_property = username
|
||||
auto_sign_up = true
|
||||
# Deprecated, use sync_ttl instead
|
||||
ldap_sync_ttl = 60
|
||||
sync_ttl = 60
|
||||
whitelist =
|
||||
headers =
|
||||
enable_login_token = false
|
||||
|
||||
#################################### Auth JWT ##########################
|
||||
[auth.jwt]
|
||||
enabled = false
|
||||
header_name =
|
||||
email_claim =
|
||||
username_claim =
|
||||
jwk_set_url =
|
||||
jwk_set_file =
|
||||
cache_ttl = 60m
|
||||
expected_claims = {}
|
||||
key_file =
|
||||
|
||||
#################################### Auth LDAP ###########################
|
||||
[auth.ldap]
|
||||
@@ -540,40 +351,6 @@ enabled = false
|
||||
config_file = /etc/grafana/ldap.toml
|
||||
allow_sign_up = true
|
||||
|
||||
# LDAP background sync (Enterprise only)
|
||||
# At 1 am every day
|
||||
sync_cron = "0 0 1 * * *"
|
||||
active_sync_enabled = true
|
||||
|
||||
#################################### AWS ###########################
|
||||
[aws]
|
||||
# Enter a comma-separated list of allowed AWS authentication providers.
|
||||
# Options are: default (AWS SDK Default), keys (Access && secret key), credentials (Credentials field), ec2_iam_role (EC2 IAM Role)
|
||||
allowed_auth_providers = default,keys,credentials
|
||||
|
||||
# Allow AWS users to assume a role using temporary security credentials.
|
||||
# If true, assume role will be enabled for all AWS authentication providers that are specified in aws_auth_providers
|
||||
assume_role_enabled = true
|
||||
|
||||
# Specify max no of pages to be returned by the ListMetricPages API
|
||||
list_metrics_page_limit = 500
|
||||
|
||||
#################################### Azure ###############################
|
||||
[azure]
|
||||
# Azure cloud environment where Grafana is hosted
|
||||
# Possible values are AzureCloud, AzureChinaCloud, AzureUSGovernment and AzureGermanCloud
|
||||
# Default value is AzureCloud (i.e. public cloud)
|
||||
cloud = AzureCloud
|
||||
|
||||
# Specifies whether Grafana hosted in Azure service with Managed Identity configured (e.g. Azure Virtual Machines instance)
|
||||
# If enabled, the managed identity can be used for authentication of Grafana in Azure services
|
||||
# Disabled by default, needs to be explicitly enabled
|
||||
managed_identity_enabled = false
|
||||
|
||||
# Client ID to use for user-assigned managed identity
|
||||
# Should be set for user-assigned identity and should be empty for system-assigned identity
|
||||
managed_identity_client_id =
|
||||
|
||||
#################################### SMTP / Emailing #####################
|
||||
[smtp]
|
||||
enabled = false
|
||||
@@ -587,7 +364,6 @@ skip_verify = false
|
||||
from_address = admin@grafana.localhost
|
||||
from_name = Grafana
|
||||
ehlo_identity =
|
||||
startTLS_policy =
|
||||
|
||||
[emails]
|
||||
welcome_email_on_sign_up = false
|
||||
@@ -595,7 +371,7 @@ templates_pattern = emails/*.html
|
||||
|
||||
#################################### Logging ##########################
|
||||
[log]
|
||||
# Either "console", "file", "syslog". Default is console and file
|
||||
# Either "console", "file", "syslog". Default is console and file
|
||||
# Use space to separate multiple modes, e.g. "console file"
|
||||
mode = console file
|
||||
|
||||
@@ -650,25 +426,6 @@ facility =
|
||||
# Syslog tag. By default, the process' argv[0] is used.
|
||||
tag =
|
||||
|
||||
[log.frontend]
|
||||
# Should Sentry javascript agent be initialized
|
||||
enabled = false
|
||||
|
||||
# Sentry DSN if you want to send events to Sentry.
|
||||
sentry_dsn =
|
||||
|
||||
# Custom HTTP endpoint to send events captured by the Sentry agent to. Default will log the events to stdout.
|
||||
custom_endpoint = /log
|
||||
|
||||
# Rate of events to be reported between 0 (none) and 1 (all), float
|
||||
sample_rate = 1.0
|
||||
|
||||
# Requests per second limit enforced per an extended period, for Grafana backend log ingestion endpoint (/log).
|
||||
log_endpoint_requests_per_second_limit = 3
|
||||
|
||||
# Max requests accepted per short interval of time for Grafana backend log ingestion endpoint (/log)
|
||||
log_endpoint_burst_limit = 15
|
||||
|
||||
#################################### Usage Quotas ########################
|
||||
[quota]
|
||||
enabled = false
|
||||
@@ -686,9 +443,6 @@ org_data_source = 10
|
||||
# limit number of api_keys per Org.
|
||||
org_api_key = 10
|
||||
|
||||
# limit number of alerts per Org.
|
||||
org_alert_rule = 100
|
||||
|
||||
# limit number of orgs a user can create.
|
||||
user_org = 10
|
||||
|
||||
@@ -707,9 +461,6 @@ global_api_key = -1
|
||||
# global limit on number of logged in users.
|
||||
global_session = -1
|
||||
|
||||
# global limit of alerts
|
||||
global_alert_rule = -1
|
||||
|
||||
#################################### Alerting ############################
|
||||
[alerting]
|
||||
# Disable alerting engine & UI features
|
||||
@@ -727,73 +478,16 @@ nodata_or_nullvalues = no_data
|
||||
# This limit will protect the server from render overloading and make sure notifications are sent out quickly
|
||||
concurrent_render_limit = 5
|
||||
|
||||
# Default setting for alert calculation timeout. Default value is 30
|
||||
evaluation_timeout_seconds = 30
|
||||
|
||||
# Default setting for alert notification timeout. Default value is 30
|
||||
notification_timeout_seconds = 30
|
||||
|
||||
# Default setting for max attempts to sending alert notifications. Default value is 3
|
||||
max_attempts = 3
|
||||
|
||||
# Makes it possible to enforce a minimal interval between evaluations, to reduce load on the backend
|
||||
min_interval_seconds = 1
|
||||
|
||||
# Configures for how long alert annotations are stored. Default is 0, which keeps them forever.
|
||||
# This setting should be expressed as an duration. Ex 6h (hours), 10d (days), 2w (weeks), 1M (month).
|
||||
max_annotation_age =
|
||||
|
||||
# Configures max number of alert annotations that Grafana stores. Default value is 0, which keeps all alert annotations.
|
||||
max_annotations_to_keep =
|
||||
|
||||
#################################### Annotations #########################
|
||||
[annotations]
|
||||
# Configures the batch size for the annotation clean-up job. This setting is used for dashboard, API, and alert annotations.
|
||||
cleanupjob_batchsize = 100
|
||||
|
||||
[annotations.dashboard]
|
||||
# Dashboard annotations means that annotations are associated with the dashboard they are created on.
|
||||
|
||||
# Configures how long dashboard annotations are stored. Default is 0, which keeps them forever.
|
||||
# This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month).
|
||||
max_age =
|
||||
|
||||
# Configures max number of dashboard annotations that Grafana stores. Default value is 0, which keeps all dashboard annotations.
|
||||
max_annotations_to_keep =
|
||||
|
||||
[annotations.api]
|
||||
# API annotations means that the annotations have been created using the API without any
|
||||
# association with a dashboard.
|
||||
|
||||
# Configures how long Grafana stores API annotations. Default is 0, which keeps them forever.
|
||||
# This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month).
|
||||
max_age =
|
||||
|
||||
# Configures max number of API annotations that Grafana keeps. Default value is 0, which keeps all API annotations.
|
||||
max_annotations_to_keep =
|
||||
|
||||
#################################### Explore #############################
|
||||
[explore]
|
||||
# Enable the Explore section
|
||||
enabled = true
|
||||
enabled = false
|
||||
|
||||
#################################### Internal Grafana Metrics ############
|
||||
# Metrics available at HTTP API Url /metrics
|
||||
[metrics]
|
||||
enabled = true
|
||||
interval_seconds = 10
|
||||
# Disable total stats (stat_totals_*) metrics to be generated
|
||||
disable_total_stats = false
|
||||
|
||||
#If both are set, basic auth will be required for the metrics endpoint.
|
||||
basic_auth_username =
|
||||
basic_auth_password =
|
||||
|
||||
# Metrics environment info adds dimensions to the `grafana_environment_info` metric, which
|
||||
# can expose more information about the Grafana instance.
|
||||
[metrics.environment_info]
|
||||
#exampleLabel1 = exampleValue1
|
||||
#exampleLabel2 = exampleValue2
|
||||
enabled = true
|
||||
interval_seconds = 10
|
||||
|
||||
# Send internal Grafana metrics to graphite
|
||||
[metrics.graphite]
|
||||
@@ -801,7 +495,6 @@ basic_auth_password =
|
||||
address =
|
||||
prefix = prod.grafana.%(instance_name)s.
|
||||
|
||||
#################################### Grafana.com integration ##########################
|
||||
[grafana_net]
|
||||
url = https://grafana.com
|
||||
|
||||
@@ -824,23 +517,13 @@ sampler_type = const
|
||||
# and indicates the initial sampling rate before the actual one
|
||||
# is received from the mothership
|
||||
sampler_param = 1
|
||||
# sampling_server_url is the URL of a sampling manager providing a sampling strategy.
|
||||
sampling_server_url =
|
||||
# Whether or not to use Zipkin span propagation (x-b3- HTTP headers).
|
||||
zipkin_propagation = false
|
||||
# Setting this to true disables shared RPC spans.
|
||||
# Not disabling is the most common setting when using Zipkin elsewhere in your infrastructure.
|
||||
disable_shared_zipkin_spans = false
|
||||
|
||||
#################################### External Image Storage ##############
|
||||
[external_image_storage]
|
||||
# Used for uploading images to public servers so they can be included in slack/email messages.
|
||||
# You can choose between (s3, webdav, gcs, azure_blob, local)
|
||||
provider =
|
||||
|
||||
[external_image_storage.s3]
|
||||
endpoint =
|
||||
path_style_access =
|
||||
bucket_url =
|
||||
bucket =
|
||||
region =
|
||||
@@ -858,8 +541,6 @@ public_url =
|
||||
key_file =
|
||||
bucket =
|
||||
path =
|
||||
enable_signed_urls = false
|
||||
signed_url_expiration =
|
||||
|
||||
[external_image_storage.azure_blob]
|
||||
account_name =
|
||||
@@ -870,128 +551,6 @@ container_name =
|
||||
# does not require any configuration
|
||||
|
||||
[rendering]
|
||||
# Options to configure a remote HTTP image rendering service, e.g. using https://github.com/grafana/grafana-image-renderer.
|
||||
# URL to a remote HTTP image renderer service, e.g. http://localhost:8081/render, will enable Grafana to render panels and dashboards to PNG-images using HTTP requests to an external service.
|
||||
# Options to configure external image rendering server like https://github.com/grafana/grafana-image-renderer
|
||||
server_url =
|
||||
# If the remote HTTP image renderer service runs on a different server than the Grafana server you may have to configure this to a URL where Grafana is reachable, e.g. http://grafana.domain/.
|
||||
callback_url =
|
||||
# Concurrent render request limit affects when the /render HTTP endpoint is used. Rendering many images at the same time can overload the server,
|
||||
# which this setting can help protect against by only allowing a certain amount of concurrent requests.
|
||||
concurrent_render_request_limit = 30
|
||||
|
||||
[panels]
|
||||
# here for to support old env variables, can remove after a few months
|
||||
enable_alpha = false
|
||||
disable_sanitize_html = false
|
||||
|
||||
[plugins]
|
||||
enable_alpha = false
|
||||
app_tls_skip_verify_insecure = false
|
||||
# Enter a comma-separated list of plugin identifiers to identify plugins to load even if they are unsigned. Plugins with modified signatures are never loaded.
|
||||
allow_loading_unsigned_plugins =
|
||||
# Enable or disable installing plugins directly from within Grafana.
|
||||
plugin_admin_enabled = false
|
||||
plugin_admin_external_manage_enabled = false
|
||||
plugin_catalog_url = https://grafana.com/grafana/plugins/
|
||||
|
||||
#################################### Grafana Live ##########################################
|
||||
[live]
|
||||
# max_connections to Grafana Live WebSocket endpoint per Grafana server instance. See Grafana Live docs
|
||||
# if you are planning to make it higher than default 100 since this can require some OS and infrastructure
|
||||
# tuning. 0 disables Live, -1 means unlimited connections.
|
||||
max_connections = 100
|
||||
|
||||
# allowed_origins is a comma-separated list of origins that can establish connection with Grafana Live.
|
||||
# If not set then origin will be matched over root_url. Supports wildcard symbol "*".
|
||||
allowed_origins =
|
||||
|
||||
#################################### Grafana Image Renderer Plugin ##########################
|
||||
[plugin.grafana-image-renderer]
|
||||
# Instruct headless browser instance to use a default timezone when not provided by Grafana, e.g. when rendering panel image of alert.
|
||||
# See ICU’s metaZones.txt (https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt) for a list of supported
|
||||
# timezone IDs. Fallbacks to TZ environment variable if not set.
|
||||
rendering_timezone =
|
||||
|
||||
# Instruct headless browser instance to use a default language when not provided by Grafana, e.g. when rendering panel image of alert.
|
||||
# Please refer to the HTTP header Accept-Language to understand how to format this value, e.g. 'fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5'.
|
||||
rendering_language =
|
||||
|
||||
# Instruct headless browser instance to use a default device scale factor when not provided by Grafana, e.g. when rendering panel image of alert.
|
||||
# Default is 1. Using a higher value will produce more detailed images (higher DPI), but will require more disk space to store an image.
|
||||
rendering_viewport_device_scale_factor =
|
||||
|
||||
# Instruct headless browser instance whether to ignore HTTPS errors during navigation. Per default HTTPS errors are not ignored. Due to
|
||||
# the security risk it's not recommended to ignore HTTPS errors.
|
||||
rendering_ignore_https_errors =
|
||||
|
||||
# Instruct headless browser instance whether to capture and log verbose information when rendering an image. Default is false and will
|
||||
# only capture and log error messages. When enabled, debug messages are captured and logged as well.
|
||||
# For the verbose information to be included in the Grafana server log you have to adjust the rendering log level to debug, configure
|
||||
# [log].filter = rendering:debug.
|
||||
rendering_verbose_logging =
|
||||
|
||||
# Instruct headless browser instance whether to output its debug and error messages into running process of remote rendering service.
|
||||
# Default is false. This can be useful to enable (true) when troubleshooting.
|
||||
rendering_dumpio =
|
||||
|
||||
# Additional arguments to pass to the headless browser instance. Default is --no-sandbox. The list of Chromium flags can be found
|
||||
# here (https://peter.sh/experiments/chromium-command-line-switches/). Multiple arguments is separated with comma-character.
|
||||
rendering_args =
|
||||
|
||||
# You can configure the plugin to use a different browser binary instead of the pre-packaged version of Chromium.
|
||||
# Please note that this is not recommended, since you may encounter problems if the installed version of Chrome/Chromium is not
|
||||
# compatible with the plugin.
|
||||
rendering_chrome_bin =
|
||||
|
||||
# Instruct how headless browser instances are created. Default is 'default' and will create a new browser instance on each request.
|
||||
# Mode 'clustered' will make sure that only a maximum of browsers/incognito pages can execute concurrently.
|
||||
# Mode 'reusable' will have one browser instance and will create a new incognito page on each request.
|
||||
rendering_mode =
|
||||
|
||||
# When rendering_mode = clustered you can instruct how many browsers or incognito pages can execute concurrently. Default is 'browser'
|
||||
# and will cluster using browser instances.
|
||||
# Mode 'context' will cluster using incognito pages.
|
||||
rendering_clustering_mode =
|
||||
# When rendering_mode = clustered you can define maximum number of browser instances/incognito pages that can execute concurrently..
|
||||
rendering_clustering_max_concurrency =
|
||||
|
||||
# Limit the maximum viewport width, height and device scale factor that can be requested.
|
||||
rendering_viewport_max_width =
|
||||
rendering_viewport_max_height =
|
||||
rendering_viewport_max_device_scale_factor =
|
||||
|
||||
# Change the listening host and port of the gRPC server. Default host is 127.0.0.1 and default port is 0 and will automatically assign
|
||||
# a port not in use.
|
||||
grpc_host =
|
||||
grpc_port =
|
||||
|
||||
[enterprise]
|
||||
license_path =
|
||||
|
||||
[feature_toggles]
|
||||
# enable features, separated by spaces
|
||||
enable =
|
||||
|
||||
[date_formats]
|
||||
# For information on what formatting patterns that are supported https://momentjs.com/docs/#/displaying/
|
||||
|
||||
# Default system date format used in time range picker and other places where full time is displayed
|
||||
full_date = YYYY-MM-DD HH:mm:ss
|
||||
|
||||
# Used by graph and other places where we only show small intervals
|
||||
interval_second = HH:mm:ss
|
||||
interval_minute = HH:mm
|
||||
interval_hour = MM/DD HH:mm
|
||||
interval_day = MM/DD
|
||||
interval_month = YYYY-MM
|
||||
interval_year = YYYY
|
||||
|
||||
# Experimental feature
|
||||
use_browser_locale = false
|
||||
|
||||
# Default timezone for user preferences. Options are 'browser' for the browser local timezone or a timezone name from IANA Time Zone database, e.g. 'UTC' or 'Europe/Amsterdam' etc.
|
||||
default_timezone = browser
|
||||
|
||||
[expressions]
|
||||
# Enable or disable the expressions functionality.
|
||||
enabled = true
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
host = "127.0.0.1"
|
||||
# Default port is 389 or 636 if use_ssl = true
|
||||
port = 389
|
||||
# Set to true if LDAP server should use an encrypted TLS connection (either with STARTTLS or LDAPS)
|
||||
# Set to true if ldap server supports TLS
|
||||
use_ssl = false
|
||||
# If set to true, use LDAP with STARTTLS instead of LDAPS
|
||||
# Set to true if connect ldap server with STARTTLS pattern (create connection in insecure, then upgrade to secure connection with TLS)
|
||||
start_tls = false
|
||||
# set to true if you want to skip ssl cert validation
|
||||
ssl_skip_verify = false
|
||||
@@ -47,7 +47,7 @@ email = "email"
|
||||
|
||||
# Map ldap groups to grafana org roles
|
||||
[[servers.group_mappings]]
|
||||
group_dn = "cn=admins,ou=groups,dc=grafana,dc=org"
|
||||
group_dn = "cn=admins,dc=grafana,dc=org"
|
||||
org_role = "Admin"
|
||||
# To make user an instance admin (Grafana Admin) uncomment line below
|
||||
# grafana_admin = true
|
||||
@@ -55,7 +55,7 @@ org_role = "Admin"
|
||||
# org_id = 1
|
||||
|
||||
[[servers.group_mappings]]
|
||||
group_dn = "cn=users,ou=groups,dc=grafana,dc=org"
|
||||
group_dn = "cn=users,dc=grafana,dc=org"
|
||||
org_role = "Editor"
|
||||
|
||||
[[servers.group_mappings]]
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
# --- First LDAP Server ---
|
||||
|
||||
[[servers]]
|
||||
host = "10.0.0.1"
|
||||
port = 389
|
||||
use_ssl = false
|
||||
start_tls = false
|
||||
ssl_skip_verify = false
|
||||
bind_dn = "cn=admin,dc=grafana,dc=org"
|
||||
bind_password = 'grafana'
|
||||
search_filter = "(cn=%s)"
|
||||
search_base_dns = ["ou=users,dc=grafana,dc=org"]
|
||||
|
||||
[servers.attributes]
|
||||
name = "givenName"
|
||||
surname = "sn"
|
||||
username = "cn"
|
||||
member_of = "memberOf"
|
||||
email = "email"
|
||||
|
||||
[[servers.group_mappings]]
|
||||
group_dn = "cn=admins,ou=groups,dc=grafana,dc=org"
|
||||
org_role = "Admin"
|
||||
grafana_admin = true
|
||||
|
||||
# --- Second LDAP Server ---
|
||||
|
||||
[[servers]]
|
||||
host = "10.0.0.2"
|
||||
port = 389
|
||||
use_ssl = false
|
||||
start_tls = false
|
||||
ssl_skip_verify = false
|
||||
|
||||
bind_dn = "cn=admin,dc=grafana,dc=org"
|
||||
bind_password = 'grafana'
|
||||
search_filter = "(cn=%s)"
|
||||
search_base_dns = ["ou=users,dc=grafana,dc=org"]
|
||||
|
||||
[servers.attributes]
|
||||
name = "givenName"
|
||||
surname = "sn"
|
||||
username = "cn"
|
||||
member_of = "memberOf"
|
||||
email = "email"
|
||||
|
||||
[[servers.group_mappings]]
|
||||
group_dn = "cn=editors,ou=groups,dc=grafana,dc=org"
|
||||
org_role = "Editor"
|
||||
|
||||
[[servers.group_mappings]]
|
||||
group_dn = "*"
|
||||
org_role = "Viewer"
|
||||
@@ -1,76 +0,0 @@
|
||||
# # config file version
|
||||
# apiVersion: 1
|
||||
|
||||
# # list of default built-in role assignments that should be removed
|
||||
# removeDefaultAssignments:
|
||||
# # <string>, must be one of the Organization roles (`Viewer`, `Editor`, `Admin`) or `Grafana Admin`
|
||||
# - builtInRole: "Grafana Admin"
|
||||
# # <string>, must be one of the existing fixed roles
|
||||
# fixedRole: "fixed:permissions:admin"
|
||||
|
||||
# # list of default built-in role assignments that should be added back
|
||||
# addDefaultAssignments:
|
||||
# # <string>, must be one of the Organization roles (`Viewer`, `Editor`, `Admin`) or `Grafana Admin`
|
||||
# - builtInRole: "Admin"
|
||||
# # <string>, must be one of the existing fixed roles
|
||||
# fixedRole: "fixed:reporting:admin:read"
|
||||
|
||||
# # list of roles that should be deleted
|
||||
# deleteRoles:
|
||||
# # <string> name of the role you want to create. Required if no uid is set
|
||||
# - name: "custom:reports:editor"
|
||||
# # <string> uid of the role. Required if no name
|
||||
# uid: "customreportseditor1"
|
||||
# # <int> org id. will default to Grafana's default if not specified
|
||||
# orgId: 1
|
||||
# # <bool> force deletion revoking all grants of the role
|
||||
# force: true
|
||||
# - name: "custom:global:reports:reader"
|
||||
# uid: "customglobalreportsreader1"
|
||||
# # <bool> overwrite org id and removes a global role
|
||||
# global: true
|
||||
# force: true
|
||||
|
||||
# # list of roles to insert/update depending on what is available in the database
|
||||
# roles:
|
||||
# # <string, required> name of the role you want to create. Required
|
||||
# - name: "custom:users:editor"
|
||||
# # <string> uid of the role. Has to be unique for all orgs.
|
||||
# uid: customuserseditor1
|
||||
# # <string> description of the role, informative purpose only.
|
||||
# description: "Role for our custom user editors"
|
||||
# # <int> version of the role, Grafana will update the role when increased
|
||||
# version: 2
|
||||
# # <int> org id. will default to Grafana's default if not specified
|
||||
# orgId: 1
|
||||
# # <list> list of the permissions granted by this role
|
||||
# permissions:
|
||||
# # <string, required> action allowed
|
||||
# - action: "users:read"
|
||||
# #<string> scope it applies to
|
||||
# scope: "users:*"
|
||||
# - action: "users:write"
|
||||
# scope: "users:*"
|
||||
# - action: "users:create"
|
||||
# scope: "users:*"
|
||||
# # <list> list of builtIn roles the role should be assigned to
|
||||
# builtInRoles:
|
||||
# # <string, required> name of the builtin role you want to assign the role to
|
||||
# - name: "Editor"
|
||||
# # <int> org id. will default to the role org id
|
||||
# orgId: 1
|
||||
# - name: "custom:global:users:reader"
|
||||
# uid: "customglobalusersreader1"
|
||||
# description: "Global Role for custom user readers"
|
||||
# version: 1
|
||||
# # <bool> overwrite org id and creates a global role
|
||||
# global: true
|
||||
# permissions:
|
||||
# - action: "users:read"
|
||||
# scope: "users:*"
|
||||
# builtInRoles:
|
||||
# - name: "Viewer"
|
||||
# orgId: 1
|
||||
# - name: "Editor"
|
||||
# # <bool> overwrite org id and assign role globally
|
||||
# global: true
|
||||
@@ -5,7 +5,6 @@ apiVersion: 1
|
||||
# - name: 'default'
|
||||
# orgId: 1
|
||||
# folder: ''
|
||||
# folderUid: ''
|
||||
# type: file
|
||||
# options:
|
||||
# path: /var/lib/grafana/dashboards
|
||||
|
||||
@@ -7,7 +7,7 @@ apiVersion: 1
|
||||
# orgId: 1
|
||||
|
||||
# # list of datasources to insert/update depending
|
||||
# # on what's available in the database
|
||||
# # on what's available in the datbase
|
||||
#datasources:
|
||||
# # <string, required> name of the datasource. Required
|
||||
# - name: Graphite
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
# # config file version
|
||||
apiVersion: 1
|
||||
|
||||
# notifiers:
|
||||
# - name: default-slack-temp
|
||||
# type: slack
|
||||
# org_name: Main Org.
|
||||
# is_default: true
|
||||
# uid: notifier1
|
||||
# settings:
|
||||
# recipient: "XXX"
|
||||
# token: "xoxb"
|
||||
# uploadImage: true
|
||||
# url: https://slack.com
|
||||
# - name: default-email
|
||||
# type: email
|
||||
# org_id: 1
|
||||
# uid: notifier2
|
||||
# is_default: false
|
||||
# settings:
|
||||
# addresses: example11111@example.com
|
||||
# delete_notifiers:
|
||||
# - name: default-slack-temp
|
||||
# org_name: Main Org.
|
||||
# uid: notifier1
|
||||
@@ -1,11 +0,0 @@
|
||||
# # config file version
|
||||
apiVersion: 1
|
||||
|
||||
# apps:
|
||||
# - type: grafana-example-app
|
||||
# org_name: Main Org.
|
||||
# disabled: true
|
||||
# - type: raintank-worldping-app
|
||||
# org_id: 1
|
||||
# jsonData:
|
||||
# apiKey: "API KEY"
|
||||
629
conf/sample.ini
629
conf/sample.ini
@@ -28,7 +28,7 @@
|
||||
|
||||
#################################### Server ####################################
|
||||
[server]
|
||||
# Protocol (http, https, h2, socket)
|
||||
# Protocol (http, https, socket)
|
||||
;protocol = http
|
||||
|
||||
# The ip address to bind to, empty will bind to all interfaces
|
||||
@@ -46,10 +46,7 @@
|
||||
|
||||
# The full public facing url you use in browser, used for redirects and emails
|
||||
# If you use reverse proxy and sub path specify full url (with sub path)
|
||||
;root_url = %(protocol)s://%(domain)s:%(http_port)s/
|
||||
|
||||
# Serve Grafana from subpath specified in `root_url` setting. By default it is set to `false` for compatibility reasons.
|
||||
;serve_from_sub_path = false
|
||||
;root_url = http://localhost:3000
|
||||
|
||||
# Log web requests
|
||||
;router_logging = false
|
||||
@@ -67,13 +64,6 @@
|
||||
# Unix socket path
|
||||
;socket =
|
||||
|
||||
# CDN Url
|
||||
;cdn_url =
|
||||
|
||||
# Sets the maximum time using a duration format (5s/5m/5ms) before timing out read of an incoming request and closing idle connections.
|
||||
# `0` means there is no timeout for reading the request.
|
||||
;read_timeout = 0
|
||||
|
||||
#################################### Database ####################################
|
||||
[database]
|
||||
# You can configure the database connection by specifying type, host, name, user and password
|
||||
@@ -94,17 +84,6 @@
|
||||
# For "postgres" only, either "disable", "require" or "verify-full"
|
||||
;ssl_mode = disable
|
||||
|
||||
# Database drivers may support different transaction isolation levels.
|
||||
# Currently, only "mysql" driver supports isolation levels.
|
||||
# If the value is empty - driver's default isolation level is applied.
|
||||
# For "mysql" use "READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ" or "SERIALIZABLE".
|
||||
;isolation_level =
|
||||
|
||||
;ca_cert_path =
|
||||
;client_key_path =
|
||||
;client_cert_path =
|
||||
;server_cert_name =
|
||||
|
||||
# For "sqlite3" only, path relative to data_path setting
|
||||
;path = grafana.db
|
||||
|
||||
@@ -118,26 +97,29 @@
|
||||
;conn_max_lifetime = 14400
|
||||
|
||||
# Set to true to log the sql calls and execution times.
|
||||
;log_queries =
|
||||
log_queries =
|
||||
|
||||
# For "sqlite3" only. cache mode setting used for connecting to the database. (private, shared)
|
||||
;cache_mode = private
|
||||
#################################### Session ####################################
|
||||
[session]
|
||||
# Either "memory", "file", "redis", "mysql", "postgres", default is "file"
|
||||
;provider = file
|
||||
|
||||
################################### Data sources #########################
|
||||
[datasources]
|
||||
# Upper limit of data sources that Grafana will return. This limit is a temporary configuration and it will be deprecated when pagination will be introduced on the list data sources API.
|
||||
;datasource_limit = 5000
|
||||
# Provider config options
|
||||
# memory: not have any config yet
|
||||
# file: session dir path, is relative to grafana data_path
|
||||
# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=grafana`
|
||||
# mysql: go-sql-driver/mysql dsn config string, e.g. `user:password@tcp(127.0.0.1:3306)/database_name`
|
||||
# postgres: user=a password=b host=localhost port=5432 dbname=c sslmode=disable
|
||||
;provider_config = sessions
|
||||
|
||||
#################################### Cache server #############################
|
||||
[remote_cache]
|
||||
# Either "redis", "memcached" or "database" default is "database"
|
||||
;type = database
|
||||
# Session cookie name
|
||||
;cookie_name = grafana_sess
|
||||
|
||||
# cache connectionstring options
|
||||
# database: will use Grafana primary database.
|
||||
# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=0,ssl=false`. Only addr is required. ssl may be 'true', 'false', or 'insecure'.
|
||||
# memcache: 127.0.0.1:11211
|
||||
;connstr =
|
||||
# If you use session in https only, default is false
|
||||
;cookie_secure = false
|
||||
|
||||
# Session life time, default is 86400
|
||||
;session_life_time = 86400
|
||||
|
||||
#################################### Data proxy ###########################
|
||||
[dataproxy]
|
||||
@@ -145,42 +127,6 @@
|
||||
# This enables data proxy logging, default is false
|
||||
;logging = false
|
||||
|
||||
# How long the data proxy waits to read the headers of the response before timing out, default is 30 seconds.
|
||||
# This setting also applies to core backend HTTP data sources where query requests use an HTTP client with timeout set.
|
||||
;timeout = 30
|
||||
|
||||
# How long the data proxy waits to establish a TCP connection before timing out, default is 10 seconds.
|
||||
;dialTimeout = 10
|
||||
|
||||
# How many seconds the data proxy waits before sending a keepalive probe request.
|
||||
;keep_alive_seconds = 30
|
||||
|
||||
# How many seconds the data proxy waits for a successful TLS Handshake before timing out.
|
||||
;tls_handshake_timeout_seconds = 10
|
||||
|
||||
# How many seconds the data proxy will wait for a server's first response headers after
|
||||
# fully writing the request headers if the request has an "Expect: 100-continue"
|
||||
# header. A value of 0 will result in the body being sent immediately, without
|
||||
# waiting for the server to approve.
|
||||
;expect_continue_timeout_seconds = 1
|
||||
|
||||
# Optionally limits the total number of connections per host, including connections in the dialing,
|
||||
# active, and idle states. On limit violation, dials will block.
|
||||
# A value of zero (0) means no limit.
|
||||
;max_conns_per_host = 0
|
||||
|
||||
# The maximum number of idle connections that Grafana will keep alive.
|
||||
;max_idle_connections = 100
|
||||
|
||||
# The maximum number of idle connections per host that Grafana will keep alive.
|
||||
;max_idle_connections_per_host = 2
|
||||
|
||||
# How many seconds the data proxy keeps an idle connection open before timing out.
|
||||
;idle_conn_timeout_seconds = 90
|
||||
|
||||
# If enabled and user is not anonymous, data proxy will add X-Grafana-User header with username into the request, default is false.
|
||||
;send_user_header = false
|
||||
|
||||
#################################### Analytics ####################################
|
||||
[analytics]
|
||||
# Server reporting, sends usage counters to stats.grafana.org every 24 hours.
|
||||
@@ -189,11 +135,8 @@
|
||||
# Change this option to false to disable reporting.
|
||||
;reporting_enabled = true
|
||||
|
||||
# The name of the distributor of the Grafana instance. Ex hosted-grafana, grafana-labs
|
||||
;reporting_distributor = grafana-labs
|
||||
|
||||
# Set to false to disable all checks to https://grafana.net
|
||||
# for new versions (grafana itself and plugins), check is used
|
||||
# for new vesions (grafana itself and plugins), check is used
|
||||
# in some UI views to notify that grafana or plugin update exists
|
||||
# This option does not cause any auto updates, nor send any information
|
||||
# only a GET request to http://grafana.com to get latest versions
|
||||
@@ -202,14 +145,8 @@
|
||||
# Google Analytics universal tracking code, only enabled if you specify an id here
|
||||
;google_analytics_ua_id =
|
||||
|
||||
# Google Tag Manager ID, only enabled if you specify an id here
|
||||
;google_tag_manager_id =
|
||||
|
||||
#################################### Security ####################################
|
||||
[security]
|
||||
# disable creation of admin user on first start of grafana
|
||||
;disable_initial_admin_creation = false
|
||||
|
||||
# default admin user, created on startup
|
||||
;admin_user = admin
|
||||
|
||||
@@ -219,6 +156,11 @@
|
||||
# used for signing
|
||||
;secret_key = SW2YcwTIb9zpOOhoPsMm
|
||||
|
||||
# Auto-login remember days
|
||||
;login_remember_days = 7
|
||||
;cookie_username = grafana_user
|
||||
;cookie_remember_name = grafana_remember
|
||||
|
||||
# disable gravatar profile images
|
||||
;disable_gravatar = false
|
||||
|
||||
@@ -228,47 +170,6 @@
|
||||
# disable protection against brute force login attempts
|
||||
;disable_brute_force_login_protection = false
|
||||
|
||||
# set to true if you host Grafana behind HTTPS. default is false.
|
||||
;cookie_secure = false
|
||||
|
||||
# set cookie SameSite attribute. defaults to `lax`. can be set to "lax", "strict", "none" and "disabled"
|
||||
;cookie_samesite = lax
|
||||
|
||||
# set to true if you want to allow browsers to render Grafana in a <frame>, <iframe>, <embed> or <object>. default is false.
|
||||
;allow_embedding = false
|
||||
|
||||
# Set to true if you want to enable http strict transport security (HSTS) response header.
|
||||
# This is only sent when HTTPS is enabled in this configuration.
|
||||
# HSTS tells browsers that the site should only be accessed using HTTPS.
|
||||
;strict_transport_security = false
|
||||
|
||||
# Sets how long a browser should cache HSTS. Only applied if strict_transport_security is enabled.
|
||||
;strict_transport_security_max_age_seconds = 86400
|
||||
|
||||
# Set to true if to enable HSTS preloading option. Only applied if strict_transport_security is enabled.
|
||||
;strict_transport_security_preload = false
|
||||
|
||||
# Set to true if to enable the HSTS includeSubDomains option. Only applied if strict_transport_security is enabled.
|
||||
;strict_transport_security_subdomains = false
|
||||
|
||||
# Set to true to enable the X-Content-Type-Options response header.
|
||||
# The X-Content-Type-Options response HTTP header is a marker used by the server to indicate that the MIME types advertised
|
||||
# in the Content-Type headers should not be changed and be followed.
|
||||
;x_content_type_options = true
|
||||
|
||||
# Set to true to enable the X-XSS-Protection header, which tells browsers to stop pages from loading
|
||||
# when they detect reflected cross-site scripting (XSS) attacks.
|
||||
;x_xss_protection = true
|
||||
|
||||
# Enable adding the Content-Security-Policy header to your requests.
|
||||
# CSP allows to control resources the user agent is allowed to load and helps prevent XSS attacks.
|
||||
;content_security_policy = false
|
||||
|
||||
# Set Content Security Policy template used when adding the Content-Security-Policy header to your requests.
|
||||
# $NONCE in the template includes a random nonce.
|
||||
# $ROOT_PATH is server.root_url without the protocol.
|
||||
;content_security_policy_template = """script-src 'self' 'unsafe-eval' 'unsafe-inline' 'strict-dynamic' $NONCE;object-src 'none';font-src 'self';style-src 'self' 'unsafe-inline' blob:;img-src * data:;base-uri 'self';connect-src 'self' grafana.com ws://$ROOT_PATH wss://$ROOT_PATH;manifest-src 'self';media-src 'none';form-action 'self';"""
|
||||
|
||||
#################################### Snapshots ###########################
|
||||
[snapshots]
|
||||
# snapshot sharing options
|
||||
@@ -276,10 +177,6 @@
|
||||
;external_snapshot_url = https://snapshots-origin.raintank.io
|
||||
;external_snapshot_name = Publish to snapshot.raintank.io
|
||||
|
||||
# Set to true to enable this Grafana instance act as an external snapshot server and allow unauthenticated requests for
|
||||
# creating and deleting snapshots.
|
||||
;public_mode = false
|
||||
|
||||
# remove expired snapshot
|
||||
;snapshot_remove_expired = true
|
||||
|
||||
@@ -288,13 +185,6 @@
|
||||
# Number dashboard versions to keep (per dashboard). Default: 20, Minimum: 1
|
||||
;versions_to_keep = 20
|
||||
|
||||
# Minimum dashboard refresh interval. When set, this will restrict users to set the refresh interval of a dashboard lower than given interval. Per default this is 5 seconds.
|
||||
# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
|
||||
;min_refresh_interval = 5s
|
||||
|
||||
# Path to the default home dashboard. If this value is empty, then Grafana uses StaticRootPath + "dashboards/home.json"
|
||||
;default_home_dashboard_path =
|
||||
|
||||
#################################### Users ###############################
|
||||
[users]
|
||||
# disable user signup / registration
|
||||
@@ -306,25 +196,15 @@
|
||||
# Set to true to automatically assign new users to the default organization (id 1)
|
||||
;auto_assign_org = true
|
||||
|
||||
# Set this value to automatically add new users to the provided organization (if auto_assign_org above is set to true)
|
||||
;auto_assign_org_id = 1
|
||||
|
||||
# Default role new users will be automatically assigned (if disabled above is set to true)
|
||||
;auto_assign_org_role = Viewer
|
||||
|
||||
# Require email validation before sign up completes
|
||||
;verify_email_enabled = false
|
||||
|
||||
# Background text for the user field on the login page
|
||||
;login_hint = email or username
|
||||
;password_hint = password
|
||||
|
||||
# Default UI theme ("dark" or "light")
|
||||
;default_theme = dark
|
||||
|
||||
# Path to a custom home page. Users are only redirected to this if the default home dashboard is used. It should match a frontend route and contain a leading slash.
|
||||
; home_page =
|
||||
|
||||
# External user management, these options affect the organization users view
|
||||
;external_manage_link_url =
|
||||
;external_manage_link_name =
|
||||
@@ -333,51 +213,17 @@
|
||||
# Viewers can edit/inspect dashboard settings in the browser. But not save the dashboard.
|
||||
;viewers_can_edit = false
|
||||
|
||||
# Editors can administrate dashboard, folders and teams they create
|
||||
;editors_can_admin = false
|
||||
|
||||
# The duration in time a user invitation remains valid before expiring. This setting should be expressed as a duration. Examples: 6h (hours), 2d (days), 1w (week). Default is 24h (24 hours). The minimum supported duration is 15m (15 minutes).
|
||||
;user_invite_max_lifetime_duration = 24h
|
||||
|
||||
# Enter a comma-separated list of users login to hide them in the Grafana UI. These users are shown to Grafana admins and themselves.
|
||||
; hidden_users =
|
||||
|
||||
[auth]
|
||||
# Login cookie name
|
||||
;login_cookie_name = grafana_session
|
||||
|
||||
# The maximum lifetime (duration) an authenticated user can be inactive before being required to login at next visit. Default is 7 days (7d). This setting should be expressed as a duration, e.g. 5m (minutes), 6h (hours), 10d (days), 2w (weeks), 1M (month). The lifetime resets at each successful token rotation.
|
||||
;login_maximum_inactive_lifetime_duration =
|
||||
|
||||
# The maximum lifetime (duration) an authenticated user can be logged in since login time before being required to login. Default is 30 days (30d). This setting should be expressed as a duration, e.g. 5m (minutes), 6h (hours), 10d (days), 2w (weeks), 1M (month).
|
||||
;login_maximum_lifetime_duration =
|
||||
|
||||
# How often should auth tokens be rotated for authenticated users when being active. The default is each 10 minutes.
|
||||
;token_rotation_interval_minutes = 10
|
||||
|
||||
# Set to true to disable (hide) the login form, useful if you use OAuth, defaults to false
|
||||
;disable_login_form = false
|
||||
|
||||
# Set to true to disable the sign out link in the side menu. Useful if you use auth.proxy or auth.jwt, defaults to false
|
||||
# Set to true to disable the signout link in the side menu. useful if you use auth.proxy, defaults to false
|
||||
;disable_signout_menu = false
|
||||
|
||||
# URL to redirect the user to after sign out
|
||||
;signout_redirect_url =
|
||||
|
||||
# Set to true to attempt login with OAuth automatically, skipping the login screen.
|
||||
# This setting is ignored if multiple OAuth providers are configured.
|
||||
;oauth_auto_login = false
|
||||
|
||||
# OAuth state max age cookie duration in seconds. Defaults to 600 seconds.
|
||||
;oauth_state_cookie_max_age = 600
|
||||
|
||||
# limit of api_key seconds to live before expiration
|
||||
;api_key_max_seconds_to_live = -1
|
||||
|
||||
# Set to true to enable SigV4 authentication option for HTTP-based datasources.
|
||||
;sigv4_auth_enabled = false
|
||||
|
||||
#################################### Anonymous Auth ######################
|
||||
#################################### Anonymous Auth ##########################
|
||||
[auth.anonymous]
|
||||
# enable anonymous access
|
||||
;enabled = false
|
||||
@@ -388,10 +234,7 @@
|
||||
# specify role for unauthenticated users
|
||||
;org_role = Viewer
|
||||
|
||||
# mask the Grafana version number for unauthenticated users
|
||||
;hide_version = false
|
||||
|
||||
#################################### GitHub Auth ##########################
|
||||
#################################### Github Auth ##########################
|
||||
[auth.github]
|
||||
;enabled = false
|
||||
;allow_sign_up = true
|
||||
@@ -401,23 +244,9 @@
|
||||
;auth_url = https://github.com/login/oauth/authorize
|
||||
;token_url = https://github.com/login/oauth/access_token
|
||||
;api_url = https://api.github.com/user
|
||||
;allowed_domains =
|
||||
;team_ids =
|
||||
;allowed_organizations =
|
||||
|
||||
#################################### GitLab Auth #########################
|
||||
[auth.gitlab]
|
||||
;enabled = false
|
||||
;allow_sign_up = true
|
||||
;client_id = some_id
|
||||
;client_secret = some_secret
|
||||
;scopes = api
|
||||
;auth_url = https://gitlab.com/oauth/authorize
|
||||
;token_url = https://gitlab.com/oauth/token
|
||||
;api_url = https://gitlab.com/api/v4
|
||||
;allowed_domains =
|
||||
;allowed_groups =
|
||||
|
||||
#################################### Google Auth ##########################
|
||||
[auth.google]
|
||||
;enabled = false
|
||||
@@ -429,7 +258,24 @@
|
||||
;token_url = https://accounts.google.com/o/oauth2/token
|
||||
;api_url = https://www.googleapis.com/oauth2/v1/userinfo
|
||||
;allowed_domains =
|
||||
;hosted_domain =
|
||||
|
||||
#################################### Generic OAuth ##########################
|
||||
[auth.generic_oauth]
|
||||
;enabled = false
|
||||
;name = OAuth
|
||||
;allow_sign_up = true
|
||||
;client_id = some_id
|
||||
;client_secret = some_secret
|
||||
;scopes = user:email,read:org
|
||||
;auth_url = https://foo.bar/login/oauth/authorize
|
||||
;token_url = https://foo.bar/login/oauth/access_token
|
||||
;api_url = https://foo.bar/user
|
||||
;team_ids =
|
||||
;allowed_organizations =
|
||||
;tls_skip_verify_insecure = false
|
||||
;tls_client_cert =
|
||||
;tls_client_key =
|
||||
;tls_client_ca =
|
||||
|
||||
#################################### Grafana.com Auth ####################
|
||||
[auth.grafana_com]
|
||||
@@ -440,89 +286,18 @@
|
||||
;scopes = user:email
|
||||
;allowed_organizations =
|
||||
|
||||
#################################### Azure AD OAuth #######################
|
||||
[auth.azuread]
|
||||
;name = Azure AD
|
||||
;enabled = false
|
||||
;allow_sign_up = true
|
||||
;client_id = some_client_id
|
||||
;client_secret = some_client_secret
|
||||
;scopes = openid email profile
|
||||
;auth_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize
|
||||
;token_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
|
||||
;allowed_domains =
|
||||
;allowed_groups =
|
||||
|
||||
#################################### Okta OAuth #######################
|
||||
[auth.okta]
|
||||
;name = Okta
|
||||
;enabled = false
|
||||
;allow_sign_up = true
|
||||
;client_id = some_id
|
||||
;client_secret = some_secret
|
||||
;scopes = openid profile email groups
|
||||
;auth_url = https://<tenant-id>.okta.com/oauth2/v1/authorize
|
||||
;token_url = https://<tenant-id>.okta.com/oauth2/v1/token
|
||||
;api_url = https://<tenant-id>.okta.com/oauth2/v1/userinfo
|
||||
;allowed_domains =
|
||||
;allowed_groups =
|
||||
;role_attribute_path =
|
||||
;role_attribute_strict = false
|
||||
|
||||
#################################### Generic OAuth ##########################
|
||||
[auth.generic_oauth]
|
||||
;enabled = false
|
||||
;name = OAuth
|
||||
;allow_sign_up = true
|
||||
;client_id = some_id
|
||||
;client_secret = some_secret
|
||||
;scopes = user:email,read:org
|
||||
;empty_scopes = false
|
||||
;email_attribute_name = email:primary
|
||||
;email_attribute_path =
|
||||
;login_attribute_path =
|
||||
;name_attribute_path =
|
||||
;id_token_attribute_name =
|
||||
;auth_url = https://foo.bar/login/oauth/authorize
|
||||
;token_url = https://foo.bar/login/oauth/access_token
|
||||
;api_url = https://foo.bar/user
|
||||
;allowed_domains =
|
||||
;team_ids =
|
||||
;allowed_organizations =
|
||||
;role_attribute_path =
|
||||
;role_attribute_strict = false
|
||||
;tls_skip_verify_insecure = false
|
||||
;tls_client_cert =
|
||||
;tls_client_key =
|
||||
;tls_client_ca =
|
||||
|
||||
#################################### Basic Auth ##########################
|
||||
[auth.basic]
|
||||
;enabled = true
|
||||
|
||||
#################################### Auth Proxy ##########################
|
||||
[auth.proxy]
|
||||
;enabled = false
|
||||
;header_name = X-WEBAUTH-USER
|
||||
;header_property = username
|
||||
;auto_sign_up = true
|
||||
;sync_ttl = 60
|
||||
;ldap_sync_ttl = 60
|
||||
;whitelist = 192.168.1.1, 192.168.2.1
|
||||
;headers = Email:X-User-Email, Name:X-User-Name
|
||||
# Read the auth proxy docs for details on what the setting below enables
|
||||
;enable_login_token = false
|
||||
|
||||
#################################### Auth JWT ##########################
|
||||
[auth.jwt]
|
||||
#################################### Basic Auth ##########################
|
||||
[auth.basic]
|
||||
;enabled = true
|
||||
;header_name = X-JWT-Assertion
|
||||
;email_claim = sub
|
||||
;username_claim = sub
|
||||
;jwk_set_url = https://foo.bar/.well-known/jwks.json
|
||||
;jwk_set_file = /path/to/jwks.json
|
||||
;cache_ttl = 60m
|
||||
;expected_claims = {"aud": ["foo", "bar"]}
|
||||
;key_file = /path/to/key/file
|
||||
|
||||
#################################### Auth LDAP ##########################
|
||||
[auth.ldap]
|
||||
@@ -530,43 +305,12 @@
|
||||
;config_file = /etc/grafana/ldap.toml
|
||||
;allow_sign_up = true
|
||||
|
||||
# LDAP background sync (Enterprise only)
|
||||
# At 1 am every day
|
||||
;sync_cron = "0 0 1 * * *"
|
||||
;active_sync_enabled = true
|
||||
|
||||
#################################### AWS ###########################
|
||||
[aws]
|
||||
# Enter a comma-separated list of allowed AWS authentication providers.
|
||||
# Options are: default (AWS SDK Default), keys (Access && secret key), credentials (Credentials field), ec2_iam_role (EC2 IAM Role)
|
||||
; allowed_auth_providers = default,keys,credentials
|
||||
|
||||
# Allow AWS users to assume a role using temporary security credentials.
|
||||
# If true, assume role will be enabled for all AWS authentication providers that are specified in aws_auth_providers
|
||||
; assume_role_enabled = true
|
||||
|
||||
#################################### Azure ###############################
|
||||
[azure]
|
||||
# Azure cloud environment where Grafana is hosted
|
||||
# Possible values are AzureCloud, AzureChinaCloud, AzureUSGovernment and AzureGermanCloud
|
||||
# Default value is AzureCloud (i.e. public cloud)
|
||||
;cloud = AzureCloud
|
||||
|
||||
# Specifies whether Grafana hosted in Azure service with Managed Identity configured (e.g. Azure Virtual Machines instance)
|
||||
# If enabled, the managed identity can be used for authentication of Grafana in Azure services
|
||||
# Disabled by default, needs to be explicitly enabled
|
||||
;managed_identity_enabled = false
|
||||
|
||||
# Client ID to use for user-assigned managed identity
|
||||
# Should be set for user-assigned identity and should be empty for system-assigned identity
|
||||
;managed_identity_client_id =
|
||||
|
||||
#################################### SMTP / Emailing ##########################
|
||||
[smtp]
|
||||
;enabled = false
|
||||
;host = localhost:25
|
||||
;user =
|
||||
# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
|
||||
# If the password contains # or ; you have to wrap it with trippel quotes. Ex """#password;"""
|
||||
;password =
|
||||
;cert_file =
|
||||
;key_file =
|
||||
@@ -575,12 +319,9 @@
|
||||
;from_name = Grafana
|
||||
# EHLO identity in SMTP dialog (defaults to instance_name)
|
||||
;ehlo_identity = dashboard.example.com
|
||||
# SMTP startTLS policy (defaults to 'OpportunisticStartTLS')
|
||||
;startTLS_policy = NoStartTLS
|
||||
|
||||
[emails]
|
||||
;welcome_email_on_sign_up = false
|
||||
;templates_pattern = emails/*.html
|
||||
|
||||
#################################### Logging ##########################
|
||||
[log]
|
||||
@@ -639,66 +380,6 @@
|
||||
# Syslog tag. By default, the process' argv[0] is used.
|
||||
;tag =
|
||||
|
||||
[log.frontend]
|
||||
# Should Sentry javascript agent be initialized
|
||||
;enabled = false
|
||||
|
||||
# Sentry DSN if you want to send events to Sentry.
|
||||
;sentry_dsn =
|
||||
|
||||
# Custom HTTP endpoint to send events captured by the Sentry agent to. Default will log the events to stdout.
|
||||
;custom_endpoint = /log
|
||||
|
||||
# Rate of events to be reported between 0 (none) and 1 (all), float
|
||||
;sample_rate = 1.0
|
||||
|
||||
# Requests per second limit enforced an extended period, for Grafana backend log ingestion endpoint (/log).
|
||||
;log_endpoint_requests_per_second_limit = 3
|
||||
|
||||
# Max requests accepted per short interval of time for Grafana backend log ingestion endpoint (/log).
|
||||
;log_endpoint_burst_limit = 15
|
||||
|
||||
#################################### Usage Quotas ########################
|
||||
[quota]
|
||||
; enabled = false
|
||||
|
||||
#### set quotas to -1 to make unlimited. ####
|
||||
# limit number of users per Org.
|
||||
; org_user = 10
|
||||
|
||||
# limit number of dashboards per Org.
|
||||
; org_dashboard = 100
|
||||
|
||||
# limit number of data_sources per Org.
|
||||
; org_data_source = 10
|
||||
|
||||
# limit number of api_keys per Org.
|
||||
; org_api_key = 10
|
||||
|
||||
# limit number of alerts per Org.
|
||||
;org_alert_rule = 100
|
||||
|
||||
# limit number of orgs a user can create.
|
||||
; user_org = 10
|
||||
|
||||
# Global limit of users.
|
||||
; global_user = -1
|
||||
|
||||
# global limit of orgs.
|
||||
; global_org = -1
|
||||
|
||||
# global limit of dashboards
|
||||
; global_dashboard = -1
|
||||
|
||||
# global limit of api_keys
|
||||
; global_api_key = -1
|
||||
|
||||
# global limit on number of logged in users.
|
||||
; global_session = -1
|
||||
|
||||
# global limit of alerts
|
||||
;global_alert_rule = -1
|
||||
|
||||
#################################### Alerting ############################
|
||||
[alerting]
|
||||
# Disable alerting engine & UI features
|
||||
@@ -716,76 +397,19 @@
|
||||
# This limit will protect the server from render overloading and make sure notifications are sent out quickly
|
||||
;concurrent_render_limit = 5
|
||||
|
||||
|
||||
# Default setting for alert calculation timeout. Default value is 30
|
||||
;evaluation_timeout_seconds = 30
|
||||
|
||||
# Default setting for alert notification timeout. Default value is 30
|
||||
;notification_timeout_seconds = 30
|
||||
|
||||
# Default setting for max attempts to sending alert notifications. Default value is 3
|
||||
;max_attempts = 3
|
||||
|
||||
# Makes it possible to enforce a minimal interval between evaluations, to reduce load on the backend
|
||||
;min_interval_seconds = 1
|
||||
|
||||
# Configures for how long alert annotations are stored. Default is 0, which keeps them forever.
|
||||
# This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month).
|
||||
;max_annotation_age =
|
||||
|
||||
# Configures max number of alert annotations that Grafana stores. Default value is 0, which keeps all alert annotations.
|
||||
;max_annotations_to_keep =
|
||||
|
||||
#################################### Annotations #########################
|
||||
[annotations]
|
||||
# Configures the batch size for the annotation clean-up job. This setting is used for dashboard, API, and alert annotations.
|
||||
;cleanupjob_batchsize = 100
|
||||
|
||||
[annotations.dashboard]
|
||||
# Dashboard annotations means that annotations are associated with the dashboard they are created on.
|
||||
|
||||
# Configures how long dashboard annotations are stored. Default is 0, which keeps them forever.
|
||||
# This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month).
|
||||
;max_age =
|
||||
|
||||
# Configures max number of dashboard annotations that Grafana stores. Default value is 0, which keeps all dashboard annotations.
|
||||
;max_annotations_to_keep =
|
||||
|
||||
[annotations.api]
|
||||
# API annotations means that the annotations have been created using the API without any
|
||||
# association with a dashboard.
|
||||
|
||||
# Configures how long Grafana stores API annotations. Default is 0, which keeps them forever.
|
||||
# This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month).
|
||||
;max_age =
|
||||
|
||||
# Configures max number of API annotations that Grafana keeps. Default value is 0, which keeps all API annotations.
|
||||
;max_annotations_to_keep =
|
||||
|
||||
#################################### Explore #############################
|
||||
[explore]
|
||||
# Enable the Explore section
|
||||
;enabled = true
|
||||
;enabled = false
|
||||
|
||||
#################################### Internal Grafana Metrics ##########################
|
||||
# Metrics available at HTTP API Url /metrics
|
||||
[metrics]
|
||||
# Disable / Enable internal metrics
|
||||
;enabled = true
|
||||
# Graphite Publish interval
|
||||
|
||||
# Publish interval
|
||||
;interval_seconds = 10
|
||||
# Disable total stats (stat_totals_*) metrics to be generated
|
||||
;disable_total_stats = false
|
||||
|
||||
#If both are set, basic auth will be required for the metrics endpoint.
|
||||
; basic_auth_username =
|
||||
; basic_auth_password =
|
||||
|
||||
# Metrics environment info adds dimensions to the `grafana_environment_info` metric, which
|
||||
# can expose more information about the Grafana instance.
|
||||
[metrics.environment_info]
|
||||
#exampleLabel1 = exampleValue1
|
||||
#exampleLabel2 = exampleValue2
|
||||
|
||||
# Send internal metrics to Graphite
|
||||
[metrics.graphite]
|
||||
@@ -793,11 +417,6 @@
|
||||
;address =
|
||||
;prefix = prod.grafana.%(instance_name)s.
|
||||
|
||||
#################################### Grafana.com integration ##########################
|
||||
# Url used to import dashboards directly from Grafana.com
|
||||
[grafana_com]
|
||||
;url = https://grafana.com
|
||||
|
||||
#################################### Distributed tracing ############
|
||||
[tracing.jaeger]
|
||||
# Enable by setting the address sending traces to jaeger (ex localhost:6831)
|
||||
@@ -814,13 +433,11 @@
|
||||
# and indicates the initial sampling rate before the actual one
|
||||
# is received from the mothership
|
||||
;sampler_param = 1
|
||||
# sampling_server_url is the URL of a sampling manager providing a sampling strategy.
|
||||
;sampling_server_url =
|
||||
# Whether or not to use Zipkin propagation (x-b3- HTTP headers).
|
||||
;zipkin_propagation = false
|
||||
# Setting this to true disables shared RPC spans.
|
||||
# Not disabling is the most common setting when using Zipkin elsewhere in your infrastructure.
|
||||
;disable_shared_zipkin_spans = false
|
||||
|
||||
#################################### Grafana.com integration ##########################
|
||||
# Url used to import dashboards directly from Grafana.com
|
||||
[grafana_com]
|
||||
;url = https://grafana.com
|
||||
|
||||
#################################### External image storage ##########################
|
||||
[external_image_storage]
|
||||
@@ -829,8 +446,6 @@
|
||||
;provider =
|
||||
|
||||
[external_image_storage.s3]
|
||||
;endpoint =
|
||||
;path_style_access =
|
||||
;bucket =
|
||||
;region =
|
||||
;path =
|
||||
@@ -857,128 +472,6 @@
|
||||
# does not require any configuration
|
||||
|
||||
[rendering]
|
||||
# Options to configure a remote HTTP image rendering service, e.g. using https://github.com/grafana/grafana-image-renderer.
|
||||
# URL to a remote HTTP image renderer service, e.g. http://localhost:8081/render, will enable Grafana to render panels and dashboards to PNG-images using HTTP requests to an external service.
|
||||
# Options to configure external image rendering server like https://github.com/grafana/grafana-image-renderer
|
||||
;server_url =
|
||||
# If the remote HTTP image renderer service runs on a different server than the Grafana server you may have to configure this to a URL where Grafana is reachable, e.g. http://grafana.domain/.
|
||||
;callback_url =
|
||||
# Concurrent render request limit affects when the /render HTTP endpoint is used. Rendering many images at the same time can overload the server,
|
||||
# which this setting can help protect against by only allowing a certain amount of concurrent requests.
|
||||
;concurrent_render_request_limit = 30
|
||||
|
||||
[panels]
|
||||
# If set to true Grafana will allow script tags in text panels. Not recommended as it enable XSS vulnerabilities.
|
||||
;disable_sanitize_html = false
|
||||
|
||||
[plugins]
|
||||
;enable_alpha = false
|
||||
;app_tls_skip_verify_insecure = false
|
||||
# Enter a comma-separated list of plugin identifiers to identify plugins to load even if they are unsigned. Plugins with modified signatures are never loaded.
|
||||
;allow_loading_unsigned_plugins =
|
||||
# Enable or disable installing plugins directly from within Grafana.
|
||||
;plugin_admin_enabled = false
|
||||
;plugin_admin_external_manage_enabled = false
|
||||
;plugin_catalog_url = https://grafana.com/grafana/plugins/
|
||||
|
||||
#################################### Grafana Live ##########################################
|
||||
[live]
|
||||
# max_connections to Grafana Live WebSocket endpoint per Grafana server instance. See Grafana Live docs
|
||||
# if you are planning to make it higher than default 100 since this can require some OS and infrastructure
|
||||
# tuning. 0 disables Live, -1 means unlimited connections.
|
||||
;max_connections = 100
|
||||
|
||||
# allowed_origins is a comma-separated list of origins that can establish connection with Grafana Live.
|
||||
# If not set then origin will be matched over root_url. Supports wildcard symbol "*".
|
||||
;allowed_origins =
|
||||
|
||||
#################################### Grafana Image Renderer Plugin ##########################
|
||||
[plugin.grafana-image-renderer]
|
||||
# Instruct headless browser instance to use a default timezone when not provided by Grafana, e.g. when rendering panel image of alert.
|
||||
# See ICU’s metaZones.txt (https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt) for a list of supported
|
||||
# timezone IDs. Fallbacks to TZ environment variable if not set.
|
||||
;rendering_timezone =
|
||||
|
||||
# Instruct headless browser instance to use a default language when not provided by Grafana, e.g. when rendering panel image of alert.
|
||||
# Please refer to the HTTP header Accept-Language to understand how to format this value, e.g. 'fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5'.
|
||||
;rendering_language =
|
||||
|
||||
# Instruct headless browser instance to use a default device scale factor when not provided by Grafana, e.g. when rendering panel image of alert.
|
||||
# Default is 1. Using a higher value will produce more detailed images (higher DPI), but will require more disk space to store an image.
|
||||
;rendering_viewport_device_scale_factor =
|
||||
|
||||
# Instruct headless browser instance whether to ignore HTTPS errors during navigation. Per default HTTPS errors are not ignored. Due to
|
||||
# the security risk it's not recommended to ignore HTTPS errors.
|
||||
;rendering_ignore_https_errors =
|
||||
|
||||
# Instruct headless browser instance whether to capture and log verbose information when rendering an image. Default is false and will
|
||||
# only capture and log error messages. When enabled, debug messages are captured and logged as well.
|
||||
# For the verbose information to be included in the Grafana server log you have to adjust the rendering log level to debug, configure
|
||||
# [log].filter = rendering:debug.
|
||||
;rendering_verbose_logging =
|
||||
|
||||
# Instruct headless browser instance whether to output its debug and error messages into running process of remote rendering service.
|
||||
# Default is false. This can be useful to enable (true) when troubleshooting.
|
||||
;rendering_dumpio =
|
||||
|
||||
# Additional arguments to pass to the headless browser instance. Default is --no-sandbox. The list of Chromium flags can be found
|
||||
# here (https://peter.sh/experiments/chromium-command-line-switches/). Multiple arguments is separated with comma-character.
|
||||
;rendering_args =
|
||||
|
||||
# You can configure the plugin to use a different browser binary instead of the pre-packaged version of Chromium.
|
||||
# Please note that this is not recommended, since you may encounter problems if the installed version of Chrome/Chromium is not
|
||||
# compatible with the plugin.
|
||||
;rendering_chrome_bin =
|
||||
|
||||
# Instruct how headless browser instances are created. Default is 'default' and will create a new browser instance on each request.
|
||||
# Mode 'clustered' will make sure that only a maximum of browsers/incognito pages can execute concurrently.
|
||||
# Mode 'reusable' will have one browser instance and will create a new incognito page on each request.
|
||||
;rendering_mode =
|
||||
|
||||
# When rendering_mode = clustered you can instruct how many browsers or incognito pages can execute concurrently. Default is 'browser'
|
||||
# and will cluster using browser instances.
|
||||
# Mode 'context' will cluster using incognito pages.
|
||||
;rendering_clustering_mode =
|
||||
# When rendering_mode = clustered you can define maximum number of browser instances/incognito pages that can execute concurrently..
|
||||
;rendering_clustering_max_concurrency =
|
||||
|
||||
# Limit the maximum viewport width, height and device scale factor that can be requested.
|
||||
;rendering_viewport_max_width =
|
||||
;rendering_viewport_max_height =
|
||||
;rendering_viewport_max_device_scale_factor =
|
||||
|
||||
# Change the listening host and port of the gRPC server. Default host is 127.0.0.1 and default port is 0 and will automatically assign
|
||||
# a port not in use.
|
||||
;grpc_host =
|
||||
;grpc_port =
|
||||
|
||||
[enterprise]
|
||||
# Path to a valid Grafana Enterprise license.jwt file
|
||||
;license_path =
|
||||
|
||||
[feature_toggles]
|
||||
# enable features, separated by spaces
|
||||
;enable =
|
||||
|
||||
[date_formats]
|
||||
# For information on what formatting patterns that are supported https://momentjs.com/docs/#/displaying/
|
||||
|
||||
# Default system date format used in time range picker and other places where full time is displayed
|
||||
;full_date = YYYY-MM-DD HH:mm:ss
|
||||
|
||||
# Used by graph and other places where we only show small intervals
|
||||
;interval_second = HH:mm:ss
|
||||
;interval_minute = HH:mm
|
||||
;interval_hour = MM/DD HH:mm
|
||||
;interval_day = MM/DD
|
||||
;interval_month = YYYY-MM
|
||||
;interval_year = YYYY
|
||||
|
||||
# Experimental feature
|
||||
;use_browser_locale = false
|
||||
|
||||
# Default timezone for user preferences. Options are 'browser' for the browser local timezone or a timezone name from IANA Time Zone database, e.g. 'UTC' or 'Europe/Amsterdam' etc.
|
||||
;default_timezone = browser
|
||||
|
||||
[expressions]
|
||||
# Enable or disable the expressions functionality.
|
||||
;enabled = true
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
# Contribute
|
||||
|
||||
This directory contains guides for contributors to the Grafana project.
|
||||
|
||||
- [Create a pull request](create-pull-request.md)
|
||||
- [Contributing documentation](documentation.md)
|
||||
- [Developer guide](developer-guide.md)
|
||||
- [Triage issues](triage-issues.md)
|
||||
|
||||
The `style-guides` directory contains style guides for the Grafana software project and documentation.
|
||||
|
||||
- [Backend style guide](style-guides/backend.md) for how to style and format backend functionality and code.
|
||||
- [Documentation style guide](style-guides/documentation-style-guide.md) for how to style and format documentation.
|
||||
- [Frontend style guide](style-guides/frontend.md) for how to style and format the user-facing functionality and code.
|
||||
- [Redux framework](style-guides/redux.md) for designing the Grafana redux framework.
|
||||
- [Themes style guide](style-guides/themes.md) for designing and updating Grafana themes.
|
||||
@@ -1,13 +0,0 @@
|
||||
# Architecture
|
||||
|
||||
Are you looking to take on contributions with bigger impact? These guides help you get a better understanding of the structure and design of the Grafana codebase.
|
||||
|
||||
Learn more about the backend architecture:
|
||||
|
||||
- Part 1: [Services](backend/services.md)
|
||||
- Part 2: [Communication](backend/communication.md)
|
||||
- Part 3: [Database](backend/database.md)
|
||||
|
||||
Learn more about the frontend architecture:
|
||||
- Part 1: [Data requests](frontend-data-requests.md)
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
# Communication
|
||||
|
||||
Grafana uses a _bus_ to pass messages between different parts of the application. All communication over the bus happens synchronously.
|
||||
|
||||
There are three types of messages: _events_, _commands_, and _queries_.
|
||||
|
||||
## Events
|
||||
|
||||
An event is something that happened in the past. Since an event has already happened, you can't change it. Instead, you can react to events by triggering additional application logic to be run, whenever they occur.
|
||||
|
||||
> Because they happened in the past, event names are written in past tense, such as `UserCreated`, and `OrgUpdated`.
|
||||
|
||||
### Subscribe to an event
|
||||
|
||||
In order to react to an event, you first need to _subscribe_ to it.
|
||||
|
||||
To subscribe to an event, register an _event listener_ in the service's `Init` method:
|
||||
|
||||
```go
|
||||
func (s *MyService) Init() error {
|
||||
s.bus.AddEventListener(s.UserCreated)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MyService) UserCreated(event *events.UserCreated) error {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
**Tip:** Browse the available events in the `events` package.
|
||||
|
||||
### Publish an event
|
||||
|
||||
If you want to let other parts of the application react to changes in a service, you can publish your own events:
|
||||
|
||||
```go
|
||||
event := &events.StickersSentEvent {
|
||||
UserID: "taylor",
|
||||
Count: 1,
|
||||
}
|
||||
if err := s.bus.Publish(event); err != nil {
|
||||
return err
|
||||
}
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
A command is a request for an action to be taken. Unlike an event's fire-and-forget approach, a command can fail as it is handled. The handler will then return an error.
|
||||
|
||||
> Because we request an operation to be performed, command are written in imperative mood, such as `CreateFolderCommand`, and `DeletePlaylistCommand`.
|
||||
|
||||
### Dispatch a command
|
||||
|
||||
To dispatch a command, pass the object to the `Dispatch` method:
|
||||
|
||||
```go
|
||||
cmd := &models.SendStickersCommand {
|
||||
UserID: "taylor",
|
||||
Count: 1,
|
||||
}
|
||||
if err := s.bus.Dispatch(cmd); err != nil {
|
||||
if err == bus.ErrHandlerNotFound {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
```
|
||||
|
||||
> **Note:** `Dispatch` will return an error if no handler is registered for that command.
|
||||
|
||||
**Tip:** Browse the available commands in the `models` package.
|
||||
|
||||
### Handle commands
|
||||
|
||||
Let other parts of the application dispatch commands to a service, by registering a _command handler_:
|
||||
|
||||
To handle a command, register a command handler in the `Init` function.
|
||||
|
||||
```go
|
||||
func (s *MyService) Init() error {
|
||||
s.bus.AddHandler(s.SendStickers)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MyService) SendStickers(cmd *models.SendStickersCommand) error {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
> **Note:** The handler method may return an error if unable to complete the command.
|
||||
|
||||
## Queries
|
||||
|
||||
A command handler can optionally populate the command sent to it. This pattern is commonly used to implement _queries_.
|
||||
|
||||
### Making a query
|
||||
|
||||
To make a query, dispatch the query instance just like you would a command. When the `Dispatch` method returns, the `Results` field contains the result of the query.
|
||||
|
||||
```go
|
||||
query := &models.FindDashboardQuery{
|
||||
ID: "foo",
|
||||
}
|
||||
if err := bus.Dispatch(query); err != nil {
|
||||
return err
|
||||
}
|
||||
// The query now contains a result.
|
||||
for _, item := range query.Results {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Return query results
|
||||
|
||||
To return results for a query, set any of the fields on the query argument before returning:
|
||||
|
||||
```go
|
||||
func (s *MyService) FindDashboard(query *models.FindDashboardQuery) error {
|
||||
// ...
|
||||
query.Result = dashboard
|
||||
return nil
|
||||
}
|
||||
```
|
||||
@@ -1,123 +0,0 @@
|
||||
# Database
|
||||
|
||||
Grafana uses a database to persist settings between restarts. In fact, if you don't specify one, Grafana creates a [SQLite3](https://www.sqlite.org/) database file on your local disk. This guide explains how to store and retrieve data from the database.
|
||||
|
||||
Grafana supports the [following databases](https://grafana.com/docs/installation/requirements/#database):
|
||||
|
||||
- [MySQL](https://www.mysql.com/)
|
||||
- [PostgreSQL](https://www.postgresql.org/)
|
||||
- [SQLite3](https://www.sqlite.org/)
|
||||
|
||||
Grafana uses the [XORM](https://xorm.io) framework for persisting objects to the database. For more information on how to use XORM, refer to the [documentation](https://gobook.io/read/gitea.com/xorm/manual-en-US/).
|
||||
|
||||
[Services](services.md) don't use XORM directly. Instead, services use the _SQL store_, a special type of service that provides an abstraction for the database layer. There are two ways of using the `sqlstore`: using `sqlstore` handlers, and using the `SQLStore` instance.
|
||||
|
||||
## `sqlstore` handlers
|
||||
|
||||
> **Deprecated:** We are deprecating `sqlstore` handlers in favor of using the `SQLStore` object directly in each service. Since most services still use the `sqlstore` handlers, we still want to explain how they work.
|
||||
|
||||
The `sqlstore` package allows you to register [command handlers](communication.md#handle-commands) that either store, or retrieve objects from the database. `sqlstore` handlers are similar to services:
|
||||
|
||||
- [Services](services.md) are command handlers that _contain business logic_.
|
||||
- `sqlstore` handlers are command handlers that _access the database_.
|
||||
|
||||
### Register a `sqlstore` handler
|
||||
|
||||
> **Deprecated:** Refer to the [deprecation note for `sqlstore` handlers](#sqlstore-handlers).
|
||||
|
||||
To register a handler:
|
||||
|
||||
- Create a new file `myrepo.go` in the `sqlstore` package.
|
||||
- Create a [command handler](communication.md#handle-commands).
|
||||
- Register the handler in the `init` function:
|
||||
|
||||
```go
|
||||
func init() {
|
||||
bus.AddHandler("sql", DeleteDashboard)
|
||||
}
|
||||
|
||||
func DeleteDashboard(cmd *models.DeleteDashboardCommand) error {
|
||||
return inTransaction(func(sess *DBSession) error {
|
||||
_, err := sess.Exec("DELETE FROM dashboards WHERE dashboard_id=?", cmd.DashboardID)
|
||||
return err
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
Here, `inTransaction` is a helper function in the `sqlstore` package that provides a session, that lets you execute SQL statements.
|
||||
|
||||
## `SQLStore`
|
||||
|
||||
As opposed to a `sqlstore` handler, the `SQLStore` is a service itself. The `SQLStore` has the same responsibility however: to store and retrieve objects, to and from the database.
|
||||
|
||||
To use the `SQLStore`, inject it in your service struct:
|
||||
|
||||
```go
|
||||
type MyService struct {
|
||||
SQLStore *sqlstore.SQLStore `inject:""`
|
||||
}
|
||||
```
|
||||
|
||||
You can now make SQL queries in any of your [command handlers](communication.md#handle-commands) or [event listeners](communication.md#subscribe-to-an-event):
|
||||
|
||||
```go
|
||||
func (s *MyService) DeleteDashboard(cmd *models.DeleteDashboardCommand) error {
|
||||
if err := s.SQLStore.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
_, err := sess.Exec("DELETE FROM dashboards WHERE dashboard_id=?", cmd.DashboardID)
|
||||
return err
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
For transactions, use the `WithTransactionalDbSession` method instead.
|
||||
|
||||
## Migrations
|
||||
|
||||
As Grafana evolves, it becomes necessary to create _schema migrations_ for one or more database tables.
|
||||
|
||||
To see all the types of migrations you can add, refer to [migrations.go](/pkg/services/sqlstore/migrator/migrations.go).
|
||||
|
||||
Before you add a migration, make sure that you:
|
||||
|
||||
- Never change a migration that has been committed and pushed to main.
|
||||
- Always add new migrations, to change or undo previous migrations.
|
||||
|
||||
Add a migration using one of the following methods:
|
||||
|
||||
- Add migrations in the `migrations` package.
|
||||
- Implement the `DatabaseMigrator` for the service.
|
||||
|
||||
**Important:** If there are previous migrations for a service, use that method. By adding migrations using both methods, you risk running migrations in the wrong order.
|
||||
|
||||
### Add migrations in `migrations` package
|
||||
|
||||
Most services have their migrations located in the [migrations](/pkg/services/sqlstore/migrations/migrations.go) package.
|
||||
|
||||
To add a migration:
|
||||
|
||||
- Open the [migrations.go](/pkg/services/sqlstore/migrations/migrations.go) file.
|
||||
- In the `AddMigrations` function, find the `addXxxMigration` function for the service you want to create a migration for.
|
||||
- At the end of the `addXxxMigration` function, register your migration:
|
||||
|
||||
[Example](https://github.com/grafana/grafana/blob/00d0640b6e778ddaca021670fe851fe00982acf2/pkg/services/sqlstore/migrations/migrations.go#L55-L70)
|
||||
|
||||
### Implement `DatabaseMigrator`
|
||||
|
||||
During initialization, SQL store queries the service registry, and runs migrations for every service that implements the [DatabaseMigrator](https://github.com/grafana/grafana/blob/44c2007498c76c2dbb48e8366b4af410f1ee1b98/pkg/registry/registry.go#L101-L106) interface.
|
||||
|
||||
To add a migration:
|
||||
|
||||
- If needed, add the `AddMigration(mg *migrator.Migrator)` method to the service.
|
||||
- At the end of the `AddMigration` method, register your migration:
|
||||
|
||||
```go
|
||||
func (s *MyService) AddMigration(mg *migrator.Migrator) {
|
||||
// ...
|
||||
|
||||
mg.AddMigration("Add column age", NewAddColumnMigration(table, &Column{
|
||||
Name: "age",
|
||||
Type: migrator.DB_BigInt,
|
||||
Nullable: true,
|
||||
}))
|
||||
}
|
||||
```
|
||||
@@ -1,16 +0,0 @@
|
||||
# Package hierarchy
|
||||
|
||||
The Go package hierarchy in Grafana should be organized logically (Ben Johnson's
|
||||
[article](https://medium.com/@benbjohnson/standard-package-layout-7cdbc8391fc1) served as inspiration), according to the
|
||||
following principles:
|
||||
|
||||
* Domain types and interfaces should be in "root" packages (not necessarily at the very top, of the hierarchy, but
|
||||
logical roots)
|
||||
* Sub-packages should depend on roots - sub-packages here typically contain implementations, for example of services
|
||||
|
||||
## Practical example
|
||||
|
||||
The `pkg/plugins` package contains plugin domain types, for example `DataPlugin`, and also interfaces
|
||||
such as `RequestHandler`. Then you have the `pkg/plugins/managers` subpackage, which contains concrete implementations
|
||||
such as the service `PluginManager`. The subpackage `pkg/plugins/backendplugin/coreplugin` contains `plugins.DataPlugin`
|
||||
implementations.
|
||||
@@ -1,69 +0,0 @@
|
||||
# Services
|
||||
|
||||
A Grafana _service_ encapsulates and exposes application logic to the rest of the application, through a set of related operations.
|
||||
|
||||
Before a service can start communicating with the rest of Grafana, it needs to be registered in the _service registry_.
|
||||
|
||||
The service registry keeps track of all available services during runtime. On start-up, Grafana uses the registry to build a dependency graph of services, a _service graph_.
|
||||
|
||||
Even though the services in Grafana do different things, they share a number of patterns. To better understand how a service works, let's build one from scratch!
|
||||
|
||||
## Create a service
|
||||
|
||||
To start building a service:
|
||||
|
||||
- Create a new Go package `mysvc` in the [pkg/services](/pkg/services) directory.
|
||||
- Create a `service.go` file inside your new directory.
|
||||
|
||||
All services need to implement the [Service](https://godoc.org/github.com/grafana/grafana/pkg/registry#Service) interface:
|
||||
|
||||
```go
|
||||
type MyService struct {
|
||||
}
|
||||
|
||||
func (s *MyService) Init() error {
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
The `Init` method is used to initialize and configure the service to make it ready to use. Services that return an error halt Grafana's startup process and cause the error to be logged as it exits.
|
||||
|
||||
## Register a service
|
||||
|
||||
Every service needs to be registered with the application for it to be included in the service graph.
|
||||
|
||||
To register a service, call the `registry.RegisterService` function in an `init` function within your package.
|
||||
|
||||
```go
|
||||
func init() {
|
||||
registry.RegisterService(&MyService{})
|
||||
}
|
||||
```
|
||||
|
||||
`init` functions are only run whenever a package is imported, so we also need to import the package in the application. In the `server.go` file under `pkg/server`, import the package we just created:
|
||||
|
||||
```go
|
||||
import _ "github.com/grafana/grafana/pkg/services/mysvc"
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
Grafana uses the [inject](https://github.com/facebookgo/inject) package to inject dependencies during runtime.
|
||||
|
||||
For example, to access the [bus](communication.md), add it to the `MyService` struct:
|
||||
|
||||
```go
|
||||
type MyService struct {
|
||||
Bus bus.Bus `inject:""`
|
||||
}
|
||||
```
|
||||
|
||||
You can also inject other services in the same way:
|
||||
|
||||
```go
|
||||
type MyService struct {
|
||||
Service other.Service `inject:""`
|
||||
}
|
||||
```
|
||||
|
||||
> **Note:** Any injected dependency needs to be an exported field. Any unexported fields result in a runtime error.
|
||||
@@ -1,41 +0,0 @@
|
||||
# Data requests
|
||||
|
||||
[BackendSrv](https://grafana.com/docs/grafana/latest/packages_api/runtime/backendsrv) handles all outgoing HTTP requests from Grafana. This document explains the high-level concepts used by `BackendSrv`.
|
||||
|
||||
## Canceling requests
|
||||
This section describes how canceling requests work in Grafana. While data sources can implement their own cancellation concept, we recommend that you use the method we describe here.
|
||||
|
||||
A data request can take a long time to finish. During the time between when a request starts and finishes, the user can change context. For example, the user may navigate away or issue the same request again.
|
||||
|
||||
If we wait for canceled requests to complete, it might create unnecessary load on data sources.
|
||||
|
||||
Grafana uses a concept called _request cancelation_ to cancel any ongoing request that Grafana doesn't need.
|
||||
|
||||
#### Before Grafana 7.2
|
||||
Before Grafana can cancel any data request, it has to identify that request. Grafana identifies a request using the property `requestId` [passed as options](https://github.com/grafana/grafana/blob/main/docs/sources/packages_api/runtime/backendsrvrequest.md) when you use [BackendSrv](https://grafana.com/docs/grafana/latest/packages_api/runtime/backendsrv).
|
||||
|
||||
The cancellation logic is as follows:
|
||||
- When an ongoing request discovers that an additional request with the same `requestId` has started, then Grafana will cancel the ongoing request.
|
||||
- When an ongoing request discovers that the special "cancel all requests" `requestId` was sent, then Grafana will cancel the ongoing request.
|
||||
|
||||
#### After Grafana 7.2
|
||||
Grafana 7.2 introduced an additional way of canceling requests using [RxJs](https://github.com/ReactiveX/rxjs). To support the new cancellation functionality, the data source needs to use the new `fetch` function in [BackendSrv](https://grafana.com/docs/grafana/latest/packages_api/runtime/backendsrv).
|
||||
|
||||
Migrating the core data sources to the new `fetch` function [is an ongoing process that you can read about in this issue.](https://github.com/grafana/grafana/issues/27222)
|
||||
|
||||
## Request queue
|
||||
Depending on how the web browser implements the protocol for HTTP 1.1, it will limit the number of parallel requests, lets call this limit _max_parallel_browser_request_.
|
||||
|
||||
Unless you have configured Grafana to use HTTP2, the browser limits parallel data requests according to the browser's implementation. For more information on how to enable HTTP2, refer to [Configuration](https://grafana.com/docs/grafana/latest/administration/configuration/#protocol).
|
||||
|
||||
Because there is a _max_parallel_browser_request_ limit, if some of the requests take a long time, they will block later requests and make interacting with Grafana very slow.
|
||||
|
||||
#### Before Grafana 7.2
|
||||
Not supported.
|
||||
|
||||
#### After Grafana 7.2
|
||||
Grafana uses a _request queue_ to process all incoming data requests in order while reserving a free "spot" for any requests to the Grafana API.
|
||||
|
||||
Since the first implementation of the request queue doesn't take into account what browser the user uses, the _request queue_ limit for parallel data source requests is hard-coded to 5.
|
||||
|
||||
> **Note:** Grafana instances [configured with HTTP2 ](https://grafana.com/docs/grafana/latest/administration/configuration/#protocol) will have a hard coded limit of 1000.
|
||||
@@ -1,107 +0,0 @@
|
||||
# Create a pull request
|
||||
|
||||
We're excited that you're considering making a contribution to the Grafana project! This document guides you through the process of creating a [pull request](https://help.github.com/en/articles/about-pull-requests/).
|
||||
|
||||
## Before you begin
|
||||
|
||||
We know you're excited to create your first pull request. Before we get started, read these resources first:
|
||||
|
||||
- Learn how to start [Contributing to Grafana](/CONTRIBUTING.md).
|
||||
- Make sure your code follows the relevant [style guides](/contribute/style-guides).
|
||||
|
||||
## Your first pull request
|
||||
|
||||
If this is your first time contributing to an open-source project on GitHub, make sure you read about [Creating a pull request](https://help.github.com/en/articles/creating-a-pull-request).
|
||||
|
||||
To increase the chance of having your pull request accepted, make sure your pull request follows these guidelines:
|
||||
|
||||
- Title and description matches the implementation.
|
||||
- Commits within the pull request follow the [Formatting guidelines](#Formatting-guidelines).
|
||||
- The pull request closes one related issue.
|
||||
- The pull request contains necessary tests that verify the intended behavior.
|
||||
- If your pull request has conflicts, rebase your branch onto the main branch.
|
||||
|
||||
If the pull request fixes a bug:
|
||||
|
||||
- The pull request description must include `Closes #<issue number>` or `Fixes #<issue number>`.
|
||||
- To avoid regressions, the pull request should include tests that replicate the fixed bug.
|
||||
|
||||
### Frontend-specific guidelines
|
||||
|
||||
Pull requests for frontend contributions must:
|
||||
|
||||
- Use [Emotion](/contribute/style-guides/styling.md) for styling.
|
||||
- Not increase the Angular code base.
|
||||
- Not use `any` or `{}` without reason.
|
||||
- Not contain large React components that could easily be split into several smaller components.
|
||||
- Not contain backend calls directly from components—use actions and Redux instead.
|
||||
|
||||
Pull requests for Redux contributions must:
|
||||
|
||||
- Use the `actionCreatorFactory` and `reducerFactory` helpers instead of traditional switch statement reducers in Redux. Refer to [Redux framework](/contribute/style-guides/redux.md) for more details.
|
||||
- Use `reducerTester` to test reducers. Refer to [Redux framework](/contribute/style-guides/redux.md) for more details.
|
||||
- Not contain code that mutates state in reducers or thunks.
|
||||
- Not contain code that accesses the reducers state slice directly. Instead, the code should use state selectors to access state.
|
||||
|
||||
### Backend-specific guidelines
|
||||
|
||||
Please refer to the [backend style guidelines](/contribute/style-guides/backend.md).
|
||||
|
||||
## Code review
|
||||
|
||||
Once you've created a pull request, the next step is to have someone review your change. A review is a learning opportunity for both the reviewer and the author of the pull request.
|
||||
|
||||
If you think a specific person needs to review your pull request, then you can tag them in the description or in a comment. Tag a user by typing the `@` symbol followed by their GitHub username.
|
||||
|
||||
We recommend that you read [How to do a code review](https://google.github.io/eng-practices/review/reviewer/) to learn more about code reviews.
|
||||
|
||||
## Formatting guidelines
|
||||
|
||||
A well-written pull request minimizes the time to get your change accepted. These guidelines help you write good commit messages and descriptions for your pull requests.
|
||||
|
||||
### Commit message format
|
||||
|
||||
Grafana uses the guidelines for commit messages outlined in [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/), with the following additions:
|
||||
|
||||
- Subject line must begin with the _area_ of the commit.
|
||||
- A footer in the form of an optional [keyword and issue reference](https://help.github.com/en/articles/closing-issues-using-keywords).
|
||||
|
||||
#### Area
|
||||
|
||||
The area should use upper camel case, e.g. UpperCamelCase.
|
||||
|
||||
Prefer using one of the following areas:
|
||||
|
||||
- **Build:** Changes to the build system, or external dependencies.
|
||||
- **Chore:** Changes that don't affect functionality.
|
||||
- **Dashboard:** Changes to the Dashboard feature.
|
||||
- **Docs:** Changes to documentation.
|
||||
- **Explore:** Changes to the Explore feature.
|
||||
- **Plugins:** Changes to any of the plugins.
|
||||
|
||||
For changes to data sources, the area should be the name of the data source, e.g., AzureMonitor, Graphite, and Prometheus.
|
||||
|
||||
For changes to panels, the area should be the name of the panel, suffixed with Panel, e.g., GraphPanel, SinglestatPanel, and TablePanel.
|
||||
|
||||
**Examples**
|
||||
|
||||
- `Build: Support publishing MSI to grafana.com`
|
||||
- `Explore: Add Live option for supported data sources`
|
||||
- `GraphPanel: Fix legend sorting issues`
|
||||
- `Docs: Changed url to URL in all documentation files`
|
||||
|
||||
### Pull request titles
|
||||
|
||||
The Grafana team _squashes_ all commits into one when we accept a pull request. The title of the pull request becomes the subject line of the squashed commit message. We still encourage contributors to write informative commit messages, as they becomes a part of the Git commit body.
|
||||
|
||||
We use the pull request title when we generate change logs for releases. As such, we strive to make the title as informative as possible.
|
||||
|
||||
Make sure that the title for your pull request uses the same format as the subject line in the commit message.
|
||||
|
||||
## Configuration changes
|
||||
|
||||
If your PR includes configuration changes, all of the following files must be changed correspondingly:
|
||||
|
||||
* conf/defaults.ini
|
||||
* conf/sample.ini
|
||||
* docs/sources/administration/configuration.md
|
||||
@@ -1,253 +0,0 @@
|
||||
# Developer guide
|
||||
|
||||
This guide helps you get started developing Grafana.
|
||||
|
||||
Before you begin, you might want to read [How to contribute to Grafana as a junior dev](https://medium.com/@ivanahuckova/how-to-contribute-to-grafana-as-junior-dev-c01fe3064502) by [Ivana Huckova](https://medium.com/@ivanahuckova).
|
||||
|
||||
## Dependencies
|
||||
|
||||
Make sure you have the following dependencies installed before setting up your developer environment:
|
||||
|
||||
- [Git](https://git-scm.com/)
|
||||
- [Go](https://golang.org/dl/) (see [go.mod](../go.mod#L3) for minimum required version)
|
||||
- [Node.js (Long Term Support)](https://nodejs.org)
|
||||
- [Yarn](https://yarnpkg.com)
|
||||
|
||||
### macOS
|
||||
|
||||
We recommend using [Homebrew](https://brew.sh/) for installing any missing dependencies:
|
||||
|
||||
```
|
||||
brew install git
|
||||
brew install go
|
||||
brew install node@14
|
||||
|
||||
npm install -g yarn
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
If you are running Grafana on Windows 10, we recommend installing the Windows Subsystem for Linux (WSL). For installation instructions, refer to our [Grafana setup guide for Windows environment](https://grafana.com/blog/2021/03/03/how-to-set-up-a-grafana-development-environment-on-a-windows-pc-using-wsl/).
|
||||
|
||||
## Download Grafana
|
||||
|
||||
We recommend using the Git command-line interface to download the source code for the Grafana project:
|
||||
|
||||
1. Open a terminal and run `git clone https://github.com/grafana/grafana.git`. This command downloads Grafana to a new `grafana` directory in your current directory.
|
||||
1. Open the `grafana` directory in your favorite code editor.
|
||||
|
||||
For alternative ways of cloning the Grafana repository, please refer to [GitHub's cloning a repository](https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/cloning-a-repository) documentation.
|
||||
|
||||
**Warning:** Do not use `go get` to download Grafana. Recent versions of Go have added behavior which isn't compatible with the way the Grafana repository is structured.
|
||||
|
||||
## Build Grafana
|
||||
|
||||
Grafana consists of two components; the _frontend_, and the _backend_.
|
||||
|
||||
### Frontend
|
||||
|
||||
Before we can build the frontend assets, we need to install the dependencies:
|
||||
|
||||
```
|
||||
yarn install --pure-lockfile
|
||||
```
|
||||
|
||||
After the command has finished, we can start building our source code:
|
||||
|
||||
```
|
||||
yarn start
|
||||
```
|
||||
|
||||
Once `yarn start` has built the assets, it will continue to do so whenever any of the files change. This means you don't have to manually build the assets every time you change the code.
|
||||
|
||||
Next, we'll build the web server that will serve the frontend assets we just built.
|
||||
|
||||
### Backend
|
||||
|
||||
Build and run the backend by running `make run` in the root directory of the repository. This command compiles the Go source code and starts a web server.
|
||||
|
||||
> Are you having problems with [too many open files](#troubleshooting)?
|
||||
|
||||
By default, you can access the web server at `http://localhost:3000/`.
|
||||
|
||||
Log in using the default credentials:
|
||||
|
||||
| username | password |
|
||||
| -------- | -------- |
|
||||
| `admin` | `admin` |
|
||||
|
||||
When you log in for the first time, Grafana asks you to change your password.
|
||||
|
||||
#### Building on Windows
|
||||
|
||||
The Grafana backend includes SQLite which requires GCC to compile. So in order to compile Grafana on Windows you need to install GCC. We recommend [TDM-GCC](http://tdm-gcc.tdragon.net/download). Eventually, if you use [Scoop](https://scoop.sh), you can install GCC through that.
|
||||
|
||||
You can simply build the back-end as follows: `go run build.go build`. The Grafana binaries will be in bin\\windows-amd64.
|
||||
Alternately, if you wish to use the `make` command, install [Make for Windows](http://gnuwin32.sourceforge.net/packages/make.htm) and use it in a Unix shell (f.ex. Git Bash).
|
||||
|
||||
## Test Grafana
|
||||
|
||||
The test suite consists of three types of tests: _Frontend tests_, _backend tests_, and _end-to-end tests_.
|
||||
|
||||
### Run frontend tests
|
||||
|
||||
We use [jest](https://jestjs.io/) for our frontend tests. Run them using Yarn:
|
||||
|
||||
```
|
||||
yarn test
|
||||
```
|
||||
|
||||
### Run backend tests
|
||||
|
||||
If you're developing for the backend, run the tests with the standard Go tool:
|
||||
|
||||
```
|
||||
go test -v ./pkg/...
|
||||
```
|
||||
|
||||
#### On Windows
|
||||
|
||||
Running the backend tests on Windows currently needs some tweaking, so use the build.go script:
|
||||
|
||||
```
|
||||
go run build.go test
|
||||
```
|
||||
|
||||
### Run end-to-end tests
|
||||
|
||||
The end to end tests in Grafana use [Cypress](https://www.cypress.io/) to run automated scripts in a headless Chromium browser. Read more about our [e2e framework](/contribute/style-guides/e2e.md).
|
||||
|
||||
To run the tests:
|
||||
|
||||
```
|
||||
yarn e2e
|
||||
```
|
||||
|
||||
By default, the end-to-end tests starts a Grafana instance listening on `localhost:3001`. To use a specific URL, set the `BASE_URL` environment variable:
|
||||
|
||||
```
|
||||
BASE_URL=http://localhost:3333 yarn e2e
|
||||
```
|
||||
|
||||
To follow the tests in the browser while they're running, use the `yarn e2e:debug`.
|
||||
|
||||
```
|
||||
yarn e2e:debug
|
||||
```
|
||||
|
||||
If you want to pick a test first, use the `yarn e2e:dev`, to pick a test and follow the test in the browser while it runs.
|
||||
|
||||
```
|
||||
yarn e2e:dev
|
||||
```
|
||||
|
||||
## Configure Grafana for development
|
||||
|
||||
The default configuration, `defaults.ini`, is located in the `conf` directory.
|
||||
|
||||
To override the default configuration, create a `custom.ini` file in the `conf` directory. You only need to add the options you wish to override.
|
||||
|
||||
Enable the development mode, by adding the following line in your `custom.ini`:
|
||||
|
||||
```
|
||||
app_mode = development
|
||||
```
|
||||
|
||||
### Add data sources
|
||||
|
||||
By now, you should be able to build and test a change you've made to the Grafana source code. In most cases, you need to add at least one data source to verify the change.
|
||||
|
||||
To set up data sources for your development environment, go to the [devenv](/devenv) directory in the Grafana repository:
|
||||
|
||||
```
|
||||
cd devenv
|
||||
```
|
||||
|
||||
Run the `setup.sh` script to set up a set of data sources and dashboards in your local Grafana instance. The script creates a set of data sources called **gdev-\<type\>**, and a set of dashboards located in a folder called **gdev dashboards**.
|
||||
|
||||
Some of the data sources require databases to run in the background.
|
||||
|
||||
Installing and configuring databases can be a tricky business. Grafana uses [Docker](https://docker.com) to make the task of setting up databases a little easier. Make sure you [install Docker](https://docs.docker.com/docker-for-mac/install/) before proceeding to the next step.
|
||||
|
||||
In the root directory of your Grafana repository, run the following command:
|
||||
|
||||
```
|
||||
make devenv sources=influxdb,loki
|
||||
```
|
||||
|
||||
The script generates a Docker Compose file with the databases you specify as `sources`, and runs them in the background.
|
||||
|
||||
See the repository for all the [available data sources](/devenv/docker/blocks). Note that some data sources have specific Docker images for macOS, e.g. `nginx_proxy_mac`.
|
||||
|
||||
## Build a Docker image
|
||||
|
||||
To build a Docker image, run:
|
||||
|
||||
```
|
||||
make build-docker-full
|
||||
```
|
||||
|
||||
The resulting image will be tagged as grafana/grafana:dev.
|
||||
|
||||
> **Note:** If you've already set up a local development environment, and you're running a `linux/amd64` machine, you can speed up building the Docker image:
|
||||
|
||||
1. Build the frontend: `go run build.go build-frontend`.
|
||||
1. Build the Docker image: `make build-docker-dev`.
|
||||
|
||||
**Note:** If you are using Docker for macOS, be sure to set the memory limit to be larger than 2 GiB. Otherwise, `grunt build` may fail. The memory limit settings are available under **Docker Desktop** -> **Preferences** -> **Advanced**.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Are you having issues with setting up your environment? Here are some tips that might help.
|
||||
|
||||
### Too many open files when running `make run`
|
||||
|
||||
Depending on your environment, you may have to increase the maximum number of open files allowed. For the rest of this section, we will assume you are on a Unix like OS (e.g. Linux/macOS), where you can control the maximum number of open files through the [ulimit](https://ss64.com/bash/ulimit.html) shell command.
|
||||
|
||||
To see how many open files are allowed, run:
|
||||
|
||||
```
|
||||
ulimit -a
|
||||
```
|
||||
|
||||
To change the number of open files allowed, run:
|
||||
|
||||
```
|
||||
ulimit -S -n 2048
|
||||
```
|
||||
|
||||
The number of files needed may be different on your environment. To determine the number of open files needed by `make run`, run:
|
||||
|
||||
```
|
||||
find ./conf ./pkg ./public/views | wc -l
|
||||
```
|
||||
|
||||
Another alternative is to limit the files being watched. The directories that are watched for changes are listed in the `.bra.toml` file in the root directory.
|
||||
|
||||
To retain your `ulimit` configuration, i.e. so it will be remembered for future sessions, you need to commit it to your command line shell initialization file. Which file this will be depends on the shell you are using, here are some examples:
|
||||
|
||||
- zsh -> ~/.zshrc
|
||||
- bash -> ~/.bashrc
|
||||
|
||||
Commit your ulimit configuration to your shell initialization file as follows ($LIMIT being your chosen limit and $INIT_FILE being the initialization file for your shell):
|
||||
|
||||
```
|
||||
echo ulimit -S -n $LIMIT >> $INIT_FILE
|
||||
```
|
||||
|
||||
Your command shell should read the initialization file in question every time it gets started, and apply your `ulimit` command.
|
||||
|
||||
For some people, typically using the bash shell, ulimit fails with an error similar to the following:
|
||||
|
||||
```
|
||||
ulimit: open files: cannot modify limit: Operation not permitted
|
||||
```
|
||||
|
||||
If that happens to you, chances are you've already set a lower limit and your shell won't let you set a higher one. Try looking in your shell initialization files (~/.bashrc typically), if there's already a ulimit command that you can tweak.
|
||||
|
||||
## Next steps
|
||||
|
||||
- Read our [style guides](/contribute/style-guides).
|
||||
- Learn how to [Create a pull request](/contribute/create-pull-request.md).
|
||||
- Read [How to contribute to Grafana as a junior dev](https://medium.com/@ivanahuckova/how-to-contribute-to-grafana-as-junior-dev-c01fe3064502) by [Ivana Huckova](https://medium.com/@ivanahuckova).
|
||||
- Read about the [architecture](architecture).
|
||||
@@ -1,42 +0,0 @@
|
||||
# Contributing to documentation
|
||||
|
||||
This documents guides you through the process of contributing to the Grafana documentation. Make sure you've read the guide for [Contributing to Grafana](/CONTRIBUTING.md).
|
||||
|
||||
## Your first contribution
|
||||
|
||||
If you’re unsure about where to start, check out some of our [open docs issues](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3Atype%2Fdocs).
|
||||
|
||||
Sometimes it can be difficult to understand an issue when you're just getting started. Refer to this list of [beginner-friendly issues](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3Atype%2Fdocs+label%3A"beginner+friendly") for tasks suitable for first-time contributors.
|
||||
|
||||
When you’ve found an issue you want to work on, please comment on the issue to let other people know you intend to work on it.
|
||||
|
||||
If you encounter any misspellings or violations to the style guide, please let us know by submitting an issue (or just fix them if they are minor changes).
|
||||
|
||||
On every page in the [documentation](https://grafana.com/docs/) are two links in the upper right corner:
|
||||
|
||||
- **Edit this page** takes you directly to the file on GitHub where you can contribute a fix.
|
||||
- **Request doc changes** prepares an issue on GitHub with relevant information already filled in.
|
||||
|
||||
## Join our community
|
||||
|
||||
For general discussions on documentation, you’re welcome to join the `#docs` channel on our [public Grafana Slack](http://slack.raintank.io) team.
|
||||
|
||||
## Style and formatting
|
||||
|
||||
All Grafana documentation is written using [Markdown](https://en.wikipedia.org/wiki/Markdown), and can be found in the [docs](/docs) directory in the [Grafana GitHub repository](https://github.com/grafana/grafana). The [documentation website](https://grafana.com/docs) is generated with [Hugo](https://gohugo.io) which uses [Blackfriday](https://github.com/russross/blackfriday) as its Markdown rendering engine.
|
||||
|
||||
### Documentation structure
|
||||
|
||||
The Grafana documentation is organized into topics, called _sections_. You can take a look at the current build at [grafana.com/docs/](https://grafana.com/docs/).
|
||||
|
||||
Each top-level section is located under the [docs/sources](/docs/sources) directory. Subsections are added by creating a subdirectory in the directory of the parent section.
|
||||
|
||||
For each section, an `_index.md` file provides an overview of the topic.
|
||||
|
||||
### Style guide
|
||||
|
||||
Refer to the [Documentation style guide](style-guides/documentation-style-guide.md) for information about Grafana style, word choice, and grammar conventions.
|
||||
|
||||
### Spelling
|
||||
|
||||
The [codespell](https://github.com/codespell-project/codespell) tool is run for every change to catch common misspellings.
|
||||
@@ -1,22 +0,0 @@
|
||||
# Upgrading dependencies
|
||||
|
||||
Notes on upgrading various backend dependencies.
|
||||
|
||||
# Protobuf
|
||||
|
||||
When upgrading the [protobuf](http://github.com/golang/protobuf) library in Grafana and the plugin SDK,
|
||||
you typically also want to upgrade your protobuf compiler toolchain and re-compile protobuf files:
|
||||
|
||||
```
|
||||
cd $GRAFANA
|
||||
make protobuf
|
||||
cd $GRAFANA_PLUGIN_SDK_GO
|
||||
mage protobuf
|
||||
```
|
||||
|
||||
After upgrading the protobuf dependency in Grafana and the plugin SDK, it might be wise to test that things still work,
|
||||
before making corresponding PRs:
|
||||
|
||||
* Test a plugin built with upgraded SDK on upgraded Grafana
|
||||
* Test a plugin built with non-upgraded SDK on upgraded Grafana
|
||||
* Test a plugin built with upgraded SDK on non-upgraded Grafana
|
||||
@@ -1,17 +0,0 @@
|
||||
# Grafana technical terminology
|
||||
|
||||
<!-- Keep terms in alphabetical order: -->
|
||||
|
||||
This document defines technical terms used in Grafana.
|
||||
|
||||
## TLS/SSL
|
||||
|
||||
The acronyms [TLS](https://en.wikipedia.org/wiki/Transport_Layer_Security) (Transport Layer Security and
|
||||
[SSL](https://en.wikipedia.org/wiki/SSL) (Secure Socket Layer) are both used to describe the HTTPS security layer,
|
||||
and are in practice synonymous. However, TLS is considered the current name for the technology, and SSL is considered
|
||||
[deprecated](https://tools.ietf.org/html/rfc7568).
|
||||
|
||||
As such, while both terms are in use (also in our codebase) and are indeed interchangeable, TLS is the preferred term.
|
||||
That said however, we have at Grafana Labs decided to use both acronyms in combination when referring to this type of
|
||||
technology, i.e. _TLS/SSL_. This is in order to not confuse those who may not be aware of them being synonymous,
|
||||
and SSL still being so prevalent in common discourse.
|
||||
@@ -1,100 +0,0 @@
|
||||
# Backend style guide
|
||||
|
||||
Grafana's backend has been developed for a long time with a mix of code styles. This guide explains how we want to write Go code in the future.
|
||||
|
||||
Unless stated otherwise, use the guidelines listed in the following articles:
|
||||
|
||||
- [Effective Go](https://golang.org/doc/effective_go.html)
|
||||
- [Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments)
|
||||
- [Go: Best Practices for Production Environments](http://peter.bourgon.org/go-in-production/#formatting-and-style)
|
||||
|
||||
## Linting and formatting
|
||||
|
||||
To ensure consistency across the Go codebase, we require all code to pass a number of linter checks.
|
||||
|
||||
We use the standard following linters:
|
||||
|
||||
- [gofmt](https://golang.org/cmd/gofmt/)
|
||||
- [golint](https://github.com/golang/lint)
|
||||
- [go vet](https://golang.org/cmd/vet/)
|
||||
|
||||
In addition to the standard linters, we also use:
|
||||
|
||||
- [revive](https://revive.run/) with a [custom config](https://github.com/grafana/grafana/blob/main/conf/revive.toml)
|
||||
- [GolangCI-Lint](https://github.com/golangci/golangci-lint)
|
||||
- [gosec](https://github.com/securego/gosec)
|
||||
|
||||
To run all linters, use the `lint-go` Makefile target:
|
||||
|
||||
```bash
|
||||
make lint-go
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
We value clean and readable code, that is loosely coupled and covered by unit tests. This makes it easier to collaborate and maintain the code.
|
||||
|
||||
Tests must use the standard library, `testing`. For assertions, prefer using [testify](https://github.com/stretchr/testify).
|
||||
|
||||
The majority of our tests uses [GoConvey](http://goconvey.co/) but that's something we want to avoid going forward.
|
||||
|
||||
In the `sqlstore` package we do database operations in tests and while some might say that's not suited for unit tests. We think they are fast enough and provide a lot of value.
|
||||
|
||||
### Assertions
|
||||
|
||||
Use respectively [`assert.*`](https://github.com/stretchr/testify#assert-package) functions to make assertions that
|
||||
should _not_ halt the test ("soft checks") and [`require.*`](https://github.com/stretchr/testify#require-package)
|
||||
functions to make assertions that _should_ halt the test ("hard checks"). Typically you want to use the latter type of
|
||||
check to assert that errors have or have not happened, since continuing the test after such an assertion fails is
|
||||
chaotic (the system under test will be in an undefined state) and you'll often have segfaults in practice.
|
||||
|
||||
### Sub-tests
|
||||
|
||||
Use [`t.Run`](https://golang.org/pkg/testing/#T.Run) to group sub-test cases, since it allows common setup and teardown
|
||||
code, plus lets you run each test case in isolation when debugging. Don't use `t.Run` to e.g. group assertions.
|
||||
|
||||
### Cleanup
|
||||
|
||||
Use [`t.Cleanup`](https://golang.org/pkg/testing/#T.Cleanup) to clean up resources in tests. It's a less fragile choice than `defer`, since it's independent of which
|
||||
function you call it in. It will always execute after the test is over in reverse call order (last `t.Cleanup` first, same as `defer`).
|
||||
|
||||
## Globals
|
||||
|
||||
As a general rule of thumb, avoid using global variables, since they make the code difficult to maintain and reason
|
||||
about, and to write tests for. The Grafana codebase currently does use a lot of global variables, especially when
|
||||
it comes to configuration, but that is a problem we're trying to solve.
|
||||
|
||||
## Pointers
|
||||
|
||||
In general, use value types and only reach for pointers when there's a real need. The reason being that pointers
|
||||
increase the risk of bugs, since a pointer can be nil and dereferencing a nil pointer leads to a panic (AKA segfault).
|
||||
Valid reasons to use a pointer include (but not necessarily limited to):
|
||||
|
||||
* You might need to pass a modifiable argument to a function
|
||||
* Copying an object might incur a performance hit (benchmark to check your assumptions, copying is often faster than
|
||||
allocating heap memory)
|
||||
* You might *need* `nil` to tell if a variable isn't set, although usually it's better to use the type's zero
|
||||
value to tell instead
|
||||
|
||||
## Database
|
||||
|
||||
In database related code, we follow certain patterns.
|
||||
|
||||
### Foreign keys
|
||||
|
||||
While they can be useful, we don't generally use foreign key constraints in Grafana, for historical and
|
||||
technical reasons. See this [comment](https://github.com/grafana/grafana/issues/3269#issuecomment-383328548) by Torkel
|
||||
for context.
|
||||
|
||||
### Unique columns
|
||||
|
||||
If a column, or column combination, should be unique, add a corresponding uniqueness constraint through a migration.
|
||||
|
||||
## JSON
|
||||
|
||||
The simplejson package is used a lot throughout the backend codebase, but it's legacy, so if at all possible
|
||||
avoid using it in new code. Use [json-iterator](https://github.com/json-iterator/go) instead, which is a more performant
|
||||
drop-in alternative to the standard [encoding/json](https://golang.org/pkg/encoding/json/) package. While encoding/json
|
||||
is a fine choice, profiling shows that json-iterator may be 3-4 times more efficient for encoding. We haven't profiled
|
||||
its parsing performance yet, but according to json-iterator's own benchmarks, it appears even more superior in this
|
||||
department.
|
||||
@@ -1,209 +0,0 @@
|
||||
# Guidelines for code comments in grafana-* packages
|
||||
|
||||
This document aims to give you some recommendation on how to add code comments to the exported code in the grafana packages.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Add package description](#add-package-description)
|
||||
1. [Set stability of an API](#set-stability-of-an-api)
|
||||
1. [Deprecate an API](#deprecate-an-api)
|
||||
1. [Specify parameters](#specify-parameters)
|
||||
1. [Set return values](#set-return-values)
|
||||
____
|
||||
|
||||
## Add package description
|
||||
|
||||
Each package has an overview explaining the overall responsibility and usage of the package.
|
||||
|
||||
You can document this description with [`@packageDocumentation`](https://api-extractor.com/pages/tsdoc/tag_packagedocumentation/) tag.
|
||||
|
||||
Add this tag to the `<packageRoot>/src/index.ts` entry file to have one place for the package description.
|
||||
|
||||
## Set stability of an API
|
||||
|
||||
All `exported` apis from the package should have a release tag to indicate its stability.
|
||||
|
||||
- [`@alpha`](https://api-extractor.com/pages/tsdoc/tag_alpha/) - early draft of api and will probably change.
|
||||
- [`@beta`](https://api-extractor.com/pages/tsdoc/tag_beta/) - close to being stable but might change.
|
||||
- [`@public`](https://api-extractor.com/pages/tsdoc/tag_public/) - ready for usage in production.
|
||||
- [`@internal`](https://api-extractor.com/pages/tsdoc/tag_internal/) - for internal use only.
|
||||
|
||||
### Main stability of APIs
|
||||
|
||||
Add a tag to mark the stability of the whole exported `class/interface/function/type` etc.
|
||||
|
||||
Please place the `release tag` at the bottom of the comment to make it consistent among files and easier to read.
|
||||
|
||||
**Do:**
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* Will help to create DataFrame objects and handle
|
||||
* the heavy lifting of creating a complex object.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const dataFrame = factory.create();
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
**/
|
||||
export class DataFrameFactory {
|
||||
create(): DataFrame { }
|
||||
}
|
||||
```
|
||||
|
||||
**Don't**
|
||||
```typescript
|
||||
/**
|
||||
* Will help to create DataFrame objects and handle
|
||||
* the heavy lifting of creating a complex object.
|
||||
*
|
||||
* @public
|
||||
* @example
|
||||
* ```typescript
|
||||
* const dataFrame = factory.create();
|
||||
* ```
|
||||
**/
|
||||
export class DataFrameFactory {
|
||||
create(): DataFrame { }
|
||||
}
|
||||
```
|
||||
|
||||
### Partial stability of APIs
|
||||
|
||||
Add the main stability of the API at the top according to [Main stability of API](#main-stability-of-api).
|
||||
|
||||
Then override the non-stable parts of the API with the proper [release tag](#release-tags). This should also be place at the bottom of the comment block.
|
||||
|
||||
**Do:**
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* Will help to create DataFrame objects and handle
|
||||
* the heavy lifting of creating a complex object.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const dataFrame = factory.create();
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
**/
|
||||
export class DataFrameFactory {
|
||||
create(): DataFrame { }
|
||||
|
||||
/**
|
||||
* @beta
|
||||
**/
|
||||
createMany(): DataFrames[] {}
|
||||
}
|
||||
```
|
||||
|
||||
**Don't**
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* Will help to create DataFrame objects and handle
|
||||
* the heavy lifting of creating a complex object.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const dataFrame = factory.create();
|
||||
* ```
|
||||
**/
|
||||
export class DataFrameFactory {
|
||||
/**
|
||||
* @public
|
||||
**/
|
||||
create(): DataFrame { }
|
||||
|
||||
/**
|
||||
* @beta
|
||||
**/
|
||||
createMany(): DataFrame[] {}
|
||||
}
|
||||
```
|
||||
|
||||
## Deprecate an API
|
||||
If you want to mark an API as deprecated to signal that this API will be removed in the future, then add the [`@deprecated`](https://api-extractor.com/pages/tsdoc/tag_deprecated/) tag.
|
||||
|
||||
If applicable add a reason why the API is deprecated directly after the `@deprecated tag`.
|
||||
|
||||
## Specify parameters
|
||||
If you want to specify the possible parameters that can be passed to an API, then add the [`@param`](https://api-extractor.com/pages/tsdoc/tag_param/) tag.
|
||||
|
||||
This attribute can be skipped if the type provided by `typescript` and the function comment or the function name is enough to explain what the parameters are.
|
||||
|
||||
**Do:**
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* Will help to create a resource resolver depending
|
||||
* on the current execution context.
|
||||
*
|
||||
* @param context - The current execution context.
|
||||
* @returns FileResolver if executed on the server otherwise a HttpResolver.
|
||||
* @public
|
||||
**/
|
||||
export const factory = (context: Context): IResolver => {
|
||||
if (context.isServer) {
|
||||
return new FileResolver();
|
||||
}
|
||||
return new HttpResolver();
|
||||
}
|
||||
```
|
||||
|
||||
**Don't**
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* Will compare two numbers to see if they are equal to each others.
|
||||
*
|
||||
* @param x - The first number
|
||||
* @param y - The second number
|
||||
* @public
|
||||
**/
|
||||
export const isEqual = (x: number, y: number): boolean => {
|
||||
return x === y;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Set return values
|
||||
If you want to specify the return value from a function you can use the [`@returns`](https://api-extractor.com/pages/tsdoc/tag_returns/) tag.
|
||||
|
||||
This attribute can be skipped if the type provided by `typescript` and the function comment or the function name is enough to explain what the function returns.
|
||||
|
||||
**Do:**
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* Will help to create a resource resolver depending
|
||||
* on the current execution context.
|
||||
*
|
||||
* @param context - The current execution context.
|
||||
* @returns FileResolver if executed on the server otherwise a HttpResolver.
|
||||
* @public
|
||||
**/
|
||||
export const factory = (context: Context): IResolver => {
|
||||
if (context.isServer) {
|
||||
return new FileResolver();
|
||||
}
|
||||
return new HttpResolver();
|
||||
}
|
||||
```
|
||||
|
||||
**Don't**
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* Will compare two numbers to see if they are equal to each others.
|
||||
*
|
||||
* @returns true if values are equal
|
||||
* @public
|
||||
**/
|
||||
export const isEqual = (x: number, y: number): boolean => {
|
||||
return x === y;
|
||||
}
|
||||
```
|
||||
@@ -1,151 +0,0 @@
|
||||
# Markdown style guide
|
||||
|
||||
This guide for Markdown style helps keep contributions consistent across all documentation created for Grafana products. Refer to the guide and update its sections as needed when a Subject Matter Expert answers a question on Markdown style, or a decision is made about how to apply Markdown.
|
||||
|
||||
## Headers
|
||||
|
||||
In Markdown, the number of "#" symbols creates different heading levels, similar to HTML heading levels:
|
||||
|
||||
**Example**
|
||||
|
||||
- \# is \<h1>.
|
||||
- \#\# is \<h2>.
|
||||
- \#\#\# is \<h3>.
|
||||
|
||||
Start your document with a single ``#`` for the title of the page. Add the sub-headings with two ``##``.
|
||||
|
||||
## Bold and emphasis
|
||||
|
||||
- Make text **bold** using two asterisks.
|
||||
|
||||
**Example:** It is ``**important**`` to use GitHub-flavored Markdown emoji consistently.
|
||||
|
||||
- Make text ``_emphasized_`` using single `` _underscores_``. Do not use the single asterisk, it can be easily confused with bold.
|
||||
|
||||
**Example:** GitHub-flavored markdown emoji should _only_ appear in specific cases.
|
||||
|
||||
|
||||
## Links and references
|
||||
|
||||
Create links to other website by wrapping the display text in square brackets, and the web URL in curved brackets.
|
||||
|
||||
\[text to display](www.website.com)
|
||||
|
||||
**Example:** For more information on including emoji in GitHub-flavored markdown, refer to the [webfx page on emoji](https://www.webfx.com/tools/emoji-cheat-sheet/) for a list of emoji.
|
||||
|
||||
## Block quotes
|
||||
|
||||
Include block quotes inside text using right-facing arrows:
|
||||
|
||||
**Example**
|
||||
|
||||
> Any important information
|
||||
> about emoji can be separated into
|
||||
> a blockquote.
|
||||
|
||||
## Code blocks
|
||||
|
||||
Code blocks written with markdown can show off syntax highlighting specific to different languages. Use three back tics to create a code block:
|
||||
|
||||
```
|
||||
function testNum(a) {
|
||||
if (a > 0) {
|
||||
return "positive";
|
||||
} else {
|
||||
return "NOT positive";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Write the name of the language after the first set of back tics, no spaces, to show specific syntax highlighting. For example; "\```javascript" produces the following:
|
||||
|
||||
```javascript
|
||||
function testNum(a) {
|
||||
if (a > 0) {
|
||||
return "positive";
|
||||
} else {
|
||||
return "NOT positive";
|
||||
}
|
||||
}
|
||||
```
|
||||
## Tables
|
||||
|
||||
Construct a table by typing the table headings, and separating them with a "|" character. Then, add a second line of dashes ("-") separated by another "|" character. When constructing the table cells, separate each cell data with another "|".
|
||||
|
||||
**Example**
|
||||
|
||||
Heading one | Heading two
|
||||
|
||||
\------------|------------
|
||||
|
||||
Cell one data| Cell two data
|
||||
|
||||
Will publish as:
|
||||
|
||||
Heading one | Heading two
|
||||
------------|------------
|
||||
Cell one data| Cell two data
|
||||
|
||||
## Lists
|
||||
|
||||
### Numbered lists
|
||||
|
||||
To avoid inconsistent list numbering, use repetitive list numbering:
|
||||
|
||||
\1. First
|
||||
|
||||
\1. Second
|
||||
|
||||
\1. Third
|
||||
|
||||
The list above will always display as:
|
||||
|
||||
1. First
|
||||
2. Second
|
||||
3. Third
|
||||
|
||||
### Unordered lists
|
||||
|
||||
Build a list of points - an unordered or unnumbered list - by using "\-" (hyphen) characters.
|
||||
|
||||
**Example**
|
||||
|
||||
- First
|
||||
- Another item
|
||||
- The last list item
|
||||
|
||||
## Images
|
||||
|
||||
_Do not_ use image shortcodes at this time.
|
||||
|
||||
Include images in a document using the following syntax:
|
||||
|
||||
```
|
||||

|
||||
```
|
||||
|
||||
> **Note:** Alt text does not appear when the user hovers the mouse over the image, but title text does.
|
||||
|
||||
**Examples:**
|
||||
|
||||
- \!\[Grafana logo](/link/to/grafanalogo/logo.png)
|
||||
- \!\[Example](/img/docs/folder_name/alert_test_rule.png)
|
||||
|
||||
This follows the format of "!", alt text wrapped in "[]" and the link URL wrapped in "()".
|
||||
|
||||
You can also use HTML such as the following:
|
||||
```
|
||||
<img src="example.png"
|
||||
alt="Example image"
|
||||
style="float: left; margin-right: 5px;" />
|
||||
```
|
||||
|
||||
In most cases, use the markdown syntax rather than the HTML syntax. Only use the HTML if you need to change the image in ways unsupported by Markdown.
|
||||
|
||||
## Comments
|
||||
|
||||
You can include comments that will not appear in published markdown using the following syntax:
|
||||
|
||||
\[comment]: <> (Comment text to display)
|
||||
|
||||
The word "comment" wrapped in "[]" followed by a ":", a space, "<>", and then the comment itself wrapped in "()".
|
||||
@@ -1,332 +0,0 @@
|
||||
# Documentation style guide
|
||||
|
||||
This style guide applies to all documentation created for Grafana products.
|
||||
|
||||
For information about how to write technical documentation, refer to the following resources:
|
||||
|
||||
* [Google Technical Writing courses](https://developers.google.com/tech-writing)
|
||||
* [Divio documentation system](https://documentation.divio.com/)
|
||||
* [Vue writing principles](https://v3.vuejs.org/guide/contributing/writing-guide.html#principles)
|
||||
|
||||
## Contributing
|
||||
|
||||
The *Documentation style guide* is a living document. Add to it whenever a style decision is made or a question is answered regarding style, grammar, or word choice.
|
||||
|
||||
## Published guides
|
||||
|
||||
For all items that are not covered in this guide, refer to the [Google developer documentation style guide](https://developers.google.com/style) and the [Microsoft style guide](https://docs.microsoft.com/en-us/style-guide/welcome/), in that order.
|
||||
|
||||
## Spelling
|
||||
|
||||
To catch common misspellings, the [codespell](https://github.com/codespell-project/codespell) tool is run for every change.
|
||||
|
||||
## Inclusive language
|
||||
|
||||
Avoid using charged language.
|
||||
|
||||
### Allowing and blocking
|
||||
|
||||
When referring to _allowing_ or _blocking_ content or traffic, use a form of _allow_ or _block_:
|
||||
|
||||
- (noun) _allowlist_ or _blocklist_
|
||||
- (verb) _allow_ or _block_
|
||||
|
||||
Example: _To **allow** outgoing traffic, add the IP to the **allowlist**._
|
||||
|
||||
Avoid _whitelist_ or _blacklist_.
|
||||
|
||||
### Primary and secondary
|
||||
|
||||
To describe relationships between nodes or processes, there are several options:
|
||||
|
||||
- Use _primary_, _main_, or _parent_, instead of _master_.
|
||||
- Use _secondary_, _replica_, or _child_, instead of _slave_.
|
||||
|
||||
Avoid _master_ or _slave_.
|
||||
|
||||
## Grafana-specific style
|
||||
|
||||
The following guidelines are specific to Grafana documentation. For the most part, these are *guidelines* are not rigid rules. If you have questions, then please ask in the #docs channel of Grafana Slack.
|
||||
|
||||
### General
|
||||
|
||||
- Use active voice:
|
||||
- Active: Grafana displays the heatmap visualization.
|
||||
- Passive: The heatmap visualization is displayed.
|
||||
- Write directly to the reader:
|
||||
- Use: "After you create a dashboard, you can add a panel to it."
|
||||
- Avoid: "After you create a dashboard, it is possible to add a panel to it."
|
||||
- Write in the imperative second person:
|
||||
- "Click the panel."
|
||||
- "Close the window."
|
||||
- Write in present tense:
|
||||
- Use: "The panel opens."
|
||||
- Avoid: "The panel will open."
|
||||
- Do not use an ampersand (&) as an abbreviation for _and_.
|
||||
- **Exceptions:** If an ampersand is used in the Grafana UI, then match the UI.
|
||||
- Avoid using internal jargon or slang.
|
||||
- Do not use two spaces after a period; use one space after a sentence.
|
||||
- Remove any extra space characters at the end of a paragraph.
|
||||
- Aim for your sentences to be fewer than 25 words. Instead, use smaller complete phrases or change the format, such as using a list.
|
||||
- Aim for paragraphs to be three sentences or fewer. Make the text more concise, use more headings, or both.
|
||||
|
||||
### File naming conventions
|
||||
|
||||
- Files that are displayed in the help system should have names that are all lowercase, no spaces. Use hyphens instead of spaces. Example: glossary.md
|
||||
- Documentation file names should match the title. **Note:** This only applies to new files at this time. Do not change the names of older files unless directed to do so.
|
||||
- Internal reference file names should be all uppercase except the file extension. Example: CONTRIBUTING.md
|
||||
- Image file names should be descriptive and unique. Also, add the software version number that the image applies to or the screenshot was taken in. Example: share-dashboard-link-7-3.png
|
||||
|
||||
### Headings
|
||||
|
||||
- Write headings in sentence case, not title case.
|
||||
- This is sentence case
|
||||
- This is Title Case
|
||||
- Task topic headings start with a verb.
|
||||
- Write a query
|
||||
- Create a dashboard
|
||||
- Concept and reference topic headings should be nouns or gerunds. Examples: Contributing to docs, Visualizations, Style guide
|
||||
|
||||
#### Heading don'ts
|
||||
|
||||
- Avoid stacked headings, which is following one heading with another heading.
|
||||
- Avoid skipping heading levels. For example, an h1 should be followed by an h2 rather than an h3.
|
||||
- Avoid having just one lower-level heading. For example, h1, h2, h2, h3, h3, h2, h2 is a good order. Do not go h1, h2, h3, h2, h3, h2.
|
||||
- Avoid using hyphens in headings.
|
||||
- Do not include parenthetical words like (Important!) in headings.
|
||||
|
||||
#### Step-by-step headings
|
||||
|
||||
In most cases, headings should not be numbered steps.
|
||||
|
||||
However, sometimes we need to use headings as numbered steps. This is mostly in cases where each step is complex or a series of other procedures. For example, in [Getting started with Grafana and Prometheus](https://grafana.com/docs/grafana/latest/getting-started/getting-started-prometheus/).
|
||||
|
||||
If that is the case, then use the following format for headings:
|
||||
|
||||
##### Step 1. Install the software
|
||||
##### Step 2. Run the software
|
||||
|
||||
### Images
|
||||
|
||||
- Preferred format is .png
|
||||
- File extension should be all lowercase.
|
||||
- Preferred DPI is 72.
|
||||
- Assume all graphics will be exclusively viewed on the web.
|
||||
- Maximum image size is 3840px X 2160px.
|
||||
- Screenshots should be readable, but not too large.
|
||||
- _Do not_ use image shortcodes. Follow the guidance in the [Grafana markdown guide](https://github.com/grafana/grafana/blob/main/contribute/style-guides/documentation-markdown-guide.md#images).
|
||||
- Markdown image links are preferred. Only use the HTML image links if you need to style the image in ways unsupported in Markdown.
|
||||
- When you name a file, follow the [file naming conventions](#file-naming-conventions). Example: image-name-7-3.png
|
||||
|
||||
### Unordered lists
|
||||
|
||||
Here are a few general rules about unordered lists. For more guidance, refer to [Lists](https://developers.google.com/style/lists) in the [Google developer style guide](https://developers.google.com/style/).
|
||||
|
||||
- List items should begin with a capital letter unless there is a strong reason not to. For example, you are listing case-sensitive parameters.
|
||||
- List items should end with periods if they are complete sentences. If one item in a list ends with a period, then apply periods to all of them.
|
||||
|
||||
### Capitalization
|
||||
|
||||
- Grafana, Loki, and Prometheus are always capitalized unless part of a code block.
|
||||
- API names are always Title Case, followed by "API"—for example, "Dashboard Permissions API"
|
||||
- Abbreviations are always capitalized (such as API, HTTP, ID, JSON, SQL, or URL) unless they are part of a code block.
|
||||
- Menu and submenu titles always use sentence case: capitalize the first word, and lowercase the rest.
|
||||
- "Dashboards" when referring to the submenu title.
|
||||
- "Keyboard shortcuts" when referring to the submenu topic.
|
||||
- Generic and plural versions are always lowercase.
|
||||
- Lowercase "dashboard" when referring to a dashboard generally.
|
||||
- Lowercase "dashboards" when referring to multiple dashboards.
|
||||
- **Exceptions:** If a term is lowercased in the Grafana UI, then match the UI.
|
||||
|
||||
#### Git, GitHub
|
||||
|
||||
Git is always capitalized, unless part of a code block. GitHub is the correct spelling and capitalization.
|
||||
|
||||
#### Integrations
|
||||
|
||||
In general, "integration" is not capitalized. Only capitalize it if it is capitalized in the UI or part of a proper noun, like the name of a specific integration.
|
||||
|
||||
The first letter of the name of an integration is always capitalized, even if the original named source is lowercase.
|
||||
|
||||
**Examples:**
|
||||
- MySQL Integration
|
||||
- CockroachDB Integration
|
||||
- Etcd Integration
|
||||
- I installed an integration on my local Grafana.
|
||||
|
||||
#### Kubernetes objects
|
||||
|
||||
Capitalize Kubernetes objects such as Job, Pod, and StatefulSet when it is clear you are specifically talking about them and not generic jobs, pods, or whatever.
|
||||
|
||||
Introduce the object as "Kubernetes XX" on the first usage, then just the object in subsequent uses.
|
||||
|
||||
**Example:**
|
||||
|
||||
Create the Kubernetes Job and check the logs to retrieve the generated token:
|
||||
|
||||
The Job requires the token be submitted as …
|
||||
|
||||
### Links and references
|
||||
|
||||
When referencing another document, use "Refer to" rather than alternatives such as "See" or "Check out."
|
||||
|
||||
Always give the reader some idea of what to expect in the reference. Avoid blind references, such as, "Refer to [this file](link)."
|
||||
|
||||
When possible, use the exact title of the page or section you are linking to as the link text.
|
||||
|
||||
**Example**
|
||||
Refer to the [Documentation style guide](documentation-style-guide.md) for information about word usage and capitalization guidelines.
|
||||
|
||||
### Notes, tips, cautions, and warnings
|
||||
|
||||
Grafana documentation uses notes, tips, cautions, and warnings. Notes are the most common. The format for all of them is indented, bold, sentence case:
|
||||
|
||||
```
|
||||
> **Note:**
|
||||
```
|
||||
|
||||
#### Notes
|
||||
|
||||
Notes provide additional information that the user should be extra aware of. For example:
|
||||
|
||||
> **Note:** This page describes a feature for Grafana 7.0 beta.
|
||||
|
||||
#### Tips
|
||||
|
||||
Tips describe alternate or more efficient ways of doing things. Rarely used.
|
||||
|
||||
#### Cautions
|
||||
|
||||
Cautions warn the user that they should proceed with caution. Use cautions to emphasize the potential downside of a course of action.
|
||||
|
||||
> **Caution:** If you turn off authentication requirements, then anyone can access your Grafana instance. This poses a considerable security risk.
|
||||
|
||||
#### Warnings
|
||||
|
||||
Warnings tell the user not to do something. For example:
|
||||
|
||||
> **Warning:** Grafana does not back up your dashboards. If you delete a dashboard, then you might not be able to recover it.
|
||||
|
||||
### Command line examples
|
||||
|
||||
- Do not assume everyone is using Linux. Make sure instructions include enough information for Windows and Mac users to successfully complete procedures.
|
||||
|
||||
- Do not add `$` before commands. Make it easy for users to copy and paste commands.
|
||||
- **Right:** `sudo yum install grafana`
|
||||
- **Wrong:** `$ sudo yum install grafana`
|
||||
|
||||
- Include `sudo` before commands that require `sudo` to work.
|
||||
|
||||
For terminal examples and Grafana configuration, use a `bash` code block:
|
||||
```bash
|
||||
sudo yum install grafana
|
||||
```
|
||||
For HTTP request/response, use an `http` code block:
|
||||
```http
|
||||
GET /api/dashboards/id/1/permissions HTTP/1.1
|
||||
Accept: application/json
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
|
||||
```
|
||||
|
||||
### Word usage
|
||||
|
||||
Grafana products has some words, abbreviations, and terms particular to the Grafana discourse community.
|
||||
|
||||
#### changelog
|
||||
|
||||
One word, not two.
|
||||
|
||||
**Example**
|
||||
|
||||
- Read the full changelog.
|
||||
|
||||
**Exception:**
|
||||
|
||||
- When referring to the file containing the official changelog, use the filename: `CHANGELOG.md`.
|
||||
|
||||
#### checkout, check out
|
||||
|
||||
Two words if used as a verb, one word if used as a noun.
|
||||
|
||||
**Examples**
|
||||
|
||||
- Check out these new features!
|
||||
- Proceed to checkout.
|
||||
|
||||
#### data source
|
||||
|
||||
Two words, not one.
|
||||
|
||||
**Exceptions:**
|
||||
- "datasource" used as an identifier
|
||||
- "datasource" in a URL
|
||||
- Use "data source" instead of "datasource" unless used as an identifier, in code, or as part of a URL.
|
||||
- Spell out "repository" and avoid the shorter "repo."
|
||||
- Use "Unix" as the preferred spelling (as opposed to "UNIX", or "unix") when referring to the family of operating systems.
|
||||
|
||||
#### display (verb)
|
||||
|
||||
*Display* is a transitive verb, which means it always needs a direct object.
|
||||
- Correct, active voice: Grafana displays your list of active alarms.
|
||||
- Correct, but passive voice: Your list of active alarms is displayed.
|
||||
- Incorrect: The list of active alarms displays.
|
||||
|
||||
#### drawer
|
||||
|
||||
Do not use. This is developer jargon that refers to a UI panel. Refer to the panel or feature by its proper name.
|
||||
|
||||
#### intro, introduction
|
||||
|
||||
"Introduction" is the preferred word. Use "intro" if there are space constraints (like on the side menu) or you are specifically trying for a less formal, more conversational tone.
|
||||
|
||||
#### metadata
|
||||
|
||||
One word, not two.
|
||||
|
||||
#### mixin
|
||||
|
||||
One word, not two. Also, not hyphenated.
|
||||
|
||||
#### open source, open-source
|
||||
|
||||
Do not hyphenate when used as an adjective unless the lack of hyphen would cause confusion. For example: _Open source software design is the most open open-source system I can imagine._
|
||||
|
||||
Do not hyphenate when it is used as a noun. For example: _Open source is the best way to develop software._
|
||||
|
||||
#### plugin, plug in
|
||||
|
||||
Two words if used as a verb, one word if used as a noun. Do not use _plug-in_.
|
||||
|
||||
**Examples**
|
||||
|
||||
- Plug in the appliance.
|
||||
- Download the plugin.
|
||||
|
||||
#### setup, set up
|
||||
|
||||
Two words if used as a verb, one word if used as a noun.
|
||||
|
||||
**Examples**
|
||||
|
||||
- Set up the workspace.
|
||||
- Initial setup might take five minutes.
|
||||
|
||||
#### node_exporter, windows_exporter
|
||||
|
||||
When referencing the Prometheus data source exporters, always use "node_exporter" and "windows_exporter" when referring to those tools.
|
||||
|
||||
**Correct:** node_exporter, windows_exporter
|
||||
**Incorrect:** Node Exporter, node exporter, Windows Exporter, Windows exporter, windows exporter.
|
||||
|
||||
#### web server
|
||||
|
||||
Two words, not one.
|
||||
|
||||
**Correct:** web server
|
||||
**Incorrect:** webserver
|
||||
|
||||
### MS SQL Server
|
||||
Always use "MS SQL" when referring to MS SQL Server application.
|
||||
|
||||
Incorrect UI spellings will be corrected in a later version of Grafana.
|
||||
@@ -1,25 +0,0 @@
|
||||
# End-to-End Tests for core Grafana
|
||||
|
||||
This document is specific to the [Grafana repository](https://github.com/grafana/grafana). Be sure that you've read the [generalized E2E document](e2e.md).
|
||||
|
||||
## Commands
|
||||
|
||||
- `yarn e2e` Creates an isolated `grafana-server` home under _\<repo-root>/e2e/tmp_ with provisioned data sources and dashboards. This copies locally build binary and frontend assets from your repo root so you need to have a built backend and frontend for this to run locally. The server starts on port 3001 so it does not conflict with your normal dev server.
|
||||
- `yarn e2e:debug` Same as above but runs the tests in chrome and does not shutdown after completion.
|
||||
- `yarn e2e:dev` Same as above but does not run any tests on startup. It lets you pick a test first.
|
||||
|
||||
If you already have a Grafana instance running, you can provide a specific URL by setting the `BASE_URL` environment variable:
|
||||
|
||||
```shell
|
||||
BASE_URL=http://172.0.10.2:3333 yarn e2e
|
||||
```
|
||||
|
||||
The above commands use some utils scripts under [_\<repo-root>/e2e_](../../e2e) that can also be used for more control.
|
||||
|
||||
- `./e2e/start-server` This creates a fresh new grafana server working dir, setup's config and starts the server. It will also kill any previously started server that is still running using pid file at _\<repo-root>/e2e/tmp/pid_.
|
||||
- `./e2e/wait-for-grafana` waits for `$HOST` and `$PORT` to be available. Per default localhost and 3001.
|
||||
- `./e2e/run-suite <debug|dev|noarg>` Starts cypress in different modes.
|
||||
|
||||
## Test suites
|
||||
|
||||
All the integration tests are located at _\<repo-root>/e2e/suite\<x>/specs_. The page objects and reusable flows are in the [_\<repo-root>/packages/grafana-e2e_](../../packages/grafana-e2e) package.
|
||||
@@ -1,28 +0,0 @@
|
||||
# End-to-End Tests for plugins
|
||||
|
||||
Be sure that you've read the [generalized E2E document](e2e.md).
|
||||
|
||||
## Commands
|
||||
|
||||
- `yarn test:e2e` will run [Grafana's E2E utility](../../packages/grafana-e2e) against an already running Grafana server.
|
||||
- `yarn test:e2e:update` will run `test:e2e` but instead of asserting that screenshots match their expected fixtures, they'll be replaced with new ones.
|
||||
|
||||
Your running Grafana instance can be targeted by setting the `CYPRESS_BASE_URL`, `CYPRESS_USERNAME` and `CYPRESS_PASSWORD` environment variableS:
|
||||
|
||||
```shell
|
||||
CYPRESS_BASE_URL=https://localhost:3000 CYPRESS_USERNAME=admin CYPRESS_PASSWORD=admin yarn test:e2e
|
||||
```
|
||||
|
||||
## Test suites
|
||||
|
||||
All tests are located at _\<repo-root>/cypress/integration_ by default.
|
||||
|
||||
## Things to test
|
||||
|
||||
- Add data source (if applicable)
|
||||
- Add panel
|
||||
- Edit panel
|
||||
- Annotations (if applicable)
|
||||
- Aliases (if applicable)
|
||||
- Template variables
|
||||
- "Explore" view
|
||||
@@ -1,162 +0,0 @@
|
||||
# End-to-End tests
|
||||
|
||||
Grafana Labs uses a minimal [homegrown solution](../../packages/grafana-e2e) built on top of [Cypress](https://cypress.io) for its end-to-end (E2E) tests.
|
||||
|
||||
Important notes:
|
||||
|
||||
- We generally store all element identifiers ([CSS selectors](https://mdn.io/docs/Web/CSS/CSS_Selectors)) within the framework for reuse and maintainability.
|
||||
- We generally do not use stubs or mocks as to fully simulate a real user.
|
||||
- Cypress' promises [do not behave as you'd expect](https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#Mixing-Async-and-Sync-code).
|
||||
- [Testing core Grafana](e2e-core.md) is slightly different than [testing plugins](e2e-plugins.md).
|
||||
|
||||
## Framework structure
|
||||
|
||||
Inspired by https://martinfowler.com/bliki/PageObject.html
|
||||
|
||||
- `Selector`: A unique identifier that is used from the E2E framework to retrieve an element from the Browser
|
||||
- `Page`: An abstraction for an object that contains one or more `Selectors` with `visit` function to navigate to the page.
|
||||
- `Component`: An abstraction for an object that contains one or more `Selectors` but without `visit` function
|
||||
- `Flow`: An abstraction that contains a sequence of actions on one or more `Pages` that can be reused and shared between tests
|
||||
|
||||
## Basic example
|
||||
|
||||
Let's start with a simple [JSX](https://reactjs.org/docs/introducing-jsx.html) example containing a single input field that we want to populate during our E2E test:
|
||||
|
||||
```jsx
|
||||
<input
|
||||
className="gf-form-input login-form-input"
|
||||
type="text"
|
||||
/>
|
||||
```
|
||||
|
||||
We _could_ target the field with a CSS selector like `.gf-form-input.login-form-input` but that would be brittle as style changes occur frequently. Furthermore there is nothing that signals to future developers that this input is part of an E2E test. At Grafana, we use `aria-label` attributes as our preferred way of defining selectors instead of [`data-*`](https://mdn.io/docs/Web/HTML/Global_attributes/data-*) as they also aid in [accessibility](https://mdn.io/docs/Learn/Accessibility/What_is_accessibility):
|
||||
|
||||
```jsx
|
||||
<input
|
||||
aria-label="Username input field"
|
||||
className="gf-form-input login-form-input"
|
||||
type="text"
|
||||
/>
|
||||
```
|
||||
|
||||
The next step is to create a `Page` representation in our E2E framework to glue the test with the real implementation using the `pageFactory` function. For that function we can supply a `url` and `selectors` like in the example below:
|
||||
|
||||
```typescript
|
||||
export const Login = {
|
||||
// Called via `Login.visit()`
|
||||
url: '/login',
|
||||
|
||||
// Called via `Login.username()`
|
||||
username: 'Username input field',
|
||||
};
|
||||
```
|
||||
|
||||
The next step is to add the `Login` page to the `Pages` export within [_\<repo-root>/packages/grafana-e2e-selectors/src/selectors/pages.ts_](../../packages/grafana-e2e-selectors/src/selectors/pages.ts) so that it appears when we type `e2e.pages` in our IDE.
|
||||
|
||||
```typescript
|
||||
export const Pages = {
|
||||
Login,
|
||||
…,
|
||||
…,
|
||||
…,
|
||||
};
|
||||
```
|
||||
|
||||
Now that we have a `Page` called `Login` in our `Pages` const we can use that to add a selector in our html like shown below and now this really signals to future developers that it is part of an E2E test.
|
||||
|
||||
```jsx
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
|
||||
<input
|
||||
aria-label={selectors.pages.Login.username}
|
||||
className="gf-form-input login-form-input"
|
||||
type="text"
|
||||
/>
|
||||
```
|
||||
|
||||
The last step in our example is to use our `Login` page as part of a test.
|
||||
|
||||
- The `url` property is used whenever we call the `visit` function and is equivalent to the Cypress' [`cy.visit()`](https://docs.cypress.io/api/commands/visit.html#Syntax).
|
||||
|
||||
- Any defined selector can be accessed from the `Login` page by invoking it. This is equivalent to the result of the Cypress function [`cy.get(…)`](https://docs.cypress.io/api/commands/get.html#Syntax).
|
||||
|
||||
```typescript
|
||||
describe('Login test', () => {
|
||||
it('passes', () => {
|
||||
e2e.pages.Login.visit();
|
||||
// To prevent flaky tests, always do a `.should` on any selector that you expect to be in the DOM.
|
||||
// Read more here: https://docs.cypress.io/guides/core-concepts/retry-ability.html#Commands-vs-assertions
|
||||
e2e.pages.Login.username()
|
||||
.should('be.visible')
|
||||
.type('admin');
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Advanced example
|
||||
|
||||
Let's take a look at an example that uses the same `selector` for multiple items in a list for instance. In this example app we have a list of data sources that we want to click on during an E2E test.
|
||||
|
||||
```jsx
|
||||
<ul>
|
||||
{dataSources.map(({ id, name }) => (
|
||||
<li className="card-item-wrapper" key={id}>
|
||||
<a className="card-item" href={`datasources/edit/${id}`}>
|
||||
<div className="card-item-name">{name}</div>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
```
|
||||
|
||||
Just as before in the basic example we'll start by creating a page abstraction using the `pageFactory` function:
|
||||
|
||||
```typescript
|
||||
export const DataSources = {
|
||||
url: '/datasources',
|
||||
dataSources: (dataSourceName: string) => `Data source list item ${dataSourceName}`,
|
||||
};
|
||||
```
|
||||
|
||||
You might have noticed that instead of a simple `string` as the `selector`, we're using a `function` that takes a string parameter as an argument and returns a formatted string using the argument.
|
||||
|
||||
Just as before we need to add the `DataSources` page to the exported const `Pages` in `packages/grafana-e2e-selectors/src/selectors/pages.ts`.
|
||||
|
||||
The next step is to use the `dataSources` selector function as in our example below:
|
||||
|
||||
```jsx
|
||||
<ul>
|
||||
{dataSources.map(({ id, name }) => (
|
||||
<li className="card-item-wrapper" key={id}>
|
||||
<a className="card-item" href={`datasources/edit/${id}`}>
|
||||
<div className="card-item-name" aria-label={selectors.pages.DataSources.dataSources(name)}>
|
||||
{name}
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
```
|
||||
|
||||
When this list is rendered with the data sources with names `A`, `B` and `C` ,the resulting HTML would look like:
|
||||
|
||||
```html
|
||||
<div class="card-item-name" aria-label="Data source list item A">A</div>
|
||||
<div class="card-item-name" aria-label="Data source list item B">B</div>
|
||||
<div class="card-item-name" aria-label="Data source list item C">C</div>
|
||||
```
|
||||
|
||||
Now we can write our test. The one thing that differs from the [basic example](#basic-example) above is that we pass in which data source we want to click on as an argument to the selector function:
|
||||
|
||||
```typescript
|
||||
describe('List test', () => {
|
||||
it('clicks on data source named B', () => {
|
||||
e2e.pages.DataSources.visit();
|
||||
// To prevent flaky tests, always do a .should on any selector that you expect to be in the DOM.
|
||||
// Read more here: https://docs.cypress.io/guides/core-concepts/retry-ability.html#Commands-vs-assertions
|
||||
e2e.pages.DataSources.dataSources('B')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
});
|
||||
});
|
||||
```
|
||||
@@ -1,349 +0,0 @@
|
||||
# Frontend Style Guide
|
||||
|
||||
Generally we follow the Airbnb [React Style Guide](https://github.com/airbnb/javascript/tree/master/react).
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Frontend Style Guide](#frontend-style-guide)
|
||||
- [Table of Contents](#table-of-contents)
|
||||
- [Basic rules](#basic-rules)
|
||||
- [Naming conventions](#naming-conventions)
|
||||
- [Use `PascalCase` for:](#use-pascalcase-for)
|
||||
- [Typescript class names](#typescript-class-names)
|
||||
- [Types and interfaces](#types-and-interfaces)
|
||||
- [Enums](#enums)
|
||||
- [Use `camelCase` for:](#use-camelcase-for)
|
||||
- [Functions](#functions)
|
||||
- [Methods](#methods)
|
||||
- [Variables](#variables)
|
||||
- [React state and properties](#react-state-and-properties)
|
||||
- [Emotion class names](#emotion-class-names)
|
||||
- [Use `ALL_CAPS` for constants.](#use-all_caps-for-constants)
|
||||
- [Use BEM convention for SASS styles.](#use-bem-convention-for-sass-styles)
|
||||
- [Typing](#typing)
|
||||
- [File and directory naming conventions](#file-and-directory-naming-conventions)
|
||||
- [Code organization](#code-organization)
|
||||
- [Exports](#exports)
|
||||
- [Comments](#comments)
|
||||
- [Linting](#linting)
|
||||
- [React](#react)
|
||||
- [Props](#props)
|
||||
- [Name callback props and handlers with an "on" prefix.](#name-callback-props-and-handlers-with-an-on-prefix)
|
||||
- [React Component definitions](#react-component-definitions)
|
||||
- [React Component constructor](#react-component-constructor)
|
||||
- [React Component defaultProps](#react-component-defaultprops)
|
||||
- [State management](#state-management)
|
||||
|
||||
- [Proposal for removing or replacing Angular dependencies](https://github.com/grafana/grafana/pull/23048)
|
||||
|
||||
## Basic rules
|
||||
|
||||
- Try to keep files small and focused.
|
||||
- Break large components up into sub-components.
|
||||
- Use spaces for indentation.
|
||||
|
||||
### Naming conventions
|
||||
|
||||
#### Use `PascalCase` for:
|
||||
|
||||
##### Typescript class names
|
||||
|
||||
```typescript
|
||||
// bad
|
||||
class dataLink {
|
||||
//...
|
||||
}
|
||||
|
||||
// good
|
||||
class DataLink {
|
||||
//...
|
||||
}
|
||||
```
|
||||
|
||||
##### Types and interfaces
|
||||
|
||||
```
|
||||
// bad
|
||||
interface buttonProps {
|
||||
//...
|
||||
}
|
||||
// bad
|
||||
interface button_props {
|
||||
//...
|
||||
}
|
||||
// bad
|
||||
interface IButtonProps {
|
||||
//...
|
||||
}
|
||||
|
||||
// good
|
||||
interface ButtonProps {
|
||||
//...
|
||||
}
|
||||
|
||||
// bad
|
||||
type requestInfo = ...
|
||||
// bad
|
||||
type request_info = ...
|
||||
|
||||
// good
|
||||
type RequestInfo = ...
|
||||
```
|
||||
|
||||
##### Enums
|
||||
|
||||
```
|
||||
// bad
|
||||
enum buttonVariant {
|
||||
//...
|
||||
}
|
||||
|
||||
// good
|
||||
enum ButtonVariant {
|
||||
//...
|
||||
}
|
||||
```
|
||||
|
||||
#### Use `camelCase` for:
|
||||
|
||||
##### Functions
|
||||
|
||||
```typescript
|
||||
// bad
|
||||
const CalculatePercentage = () => { ... }
|
||||
// bad
|
||||
const calculate_percentage = () => { ... }
|
||||
|
||||
// good
|
||||
const calculatePercentage = () => { ... }
|
||||
```
|
||||
|
||||
##### Methods
|
||||
|
||||
```typescript
|
||||
class DateCalculator {
|
||||
// bad
|
||||
CalculateTimeRange () {...}
|
||||
}
|
||||
class DateCalculator {
|
||||
// bad
|
||||
calculate_time_range () {...}
|
||||
}
|
||||
|
||||
class DateCalculator {
|
||||
// good
|
||||
calculateTimeRange () {...}
|
||||
}
|
||||
```
|
||||
|
||||
##### Variables
|
||||
|
||||
```typescript
|
||||
// bad
|
||||
const QueryTargets = [];
|
||||
// bad
|
||||
const query_targets = [];
|
||||
|
||||
// good
|
||||
const queryTargets = [];
|
||||
```
|
||||
|
||||
##### React state and properties
|
||||
|
||||
```typescript
|
||||
interface ModalState {
|
||||
// bad
|
||||
IsActive: boolean;
|
||||
// bad
|
||||
is_active: boolean;
|
||||
|
||||
// good
|
||||
isActive: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
##### Emotion class names
|
||||
|
||||
```typescript
|
||||
const getStyles = = () => ({
|
||||
// bad
|
||||
ElementWrapper: css`...`,
|
||||
// bad
|
||||
["element-wrapper"]: css`...`,
|
||||
|
||||
// good
|
||||
elementWrapper: css`...`,
|
||||
});
|
||||
```
|
||||
|
||||
#### Use `ALL_CAPS` for constants.
|
||||
|
||||
```typescript
|
||||
// bad
|
||||
const constantValue = "This string won't change";
|
||||
// bad
|
||||
const constant_value = "This string won't change";
|
||||
|
||||
// good
|
||||
const CONSTANT_VALUE = "This string won't change";
|
||||
```
|
||||
|
||||
#### Use [BEM](http://getbem.com/) convention for SASS styles.
|
||||
|
||||
_SASS styles are deprecated. Please migrate to Emotion whenever you need to modify SASS styles._
|
||||
|
||||
### Typing
|
||||
|
||||
In general, you should let Typescript infer the types so that there's no need to explicitly define type for each variable.
|
||||
|
||||
There are some exceptions to this:
|
||||
|
||||
```typescript
|
||||
// Typescript needs to know type of arrays or objects otherwise it would infer it as array of any
|
||||
|
||||
// bad
|
||||
const stringArray = [];
|
||||
|
||||
// good
|
||||
const stringArray: string[] = [];
|
||||
```
|
||||
|
||||
Specify function return types explicitly in new code. This improves readability by being able to tell what a function returns just by looking at the signature. It also prevents errors when a function's return type is broader than expected by the author.
|
||||
|
||||
> **Note:** We don't have linting for this enabled because of lots of old code that needs to be fixed first.
|
||||
|
||||
```typescript
|
||||
// bad
|
||||
function transform(value?: string) {
|
||||
if (!value) {
|
||||
return undefined
|
||||
}
|
||||
return applyTransform(value)
|
||||
};
|
||||
|
||||
// good
|
||||
function transform(value?: string): TransformedValue | undefined {
|
||||
if (!value) {
|
||||
return undefined
|
||||
}
|
||||
return applyTransform(value)
|
||||
};
|
||||
```
|
||||
|
||||
### File and directory naming conventions
|
||||
|
||||
Name files according to the primary export:
|
||||
|
||||
- When the primary export is a class or React component, use PascalCase.
|
||||
- When the primary export is a function, use camelCase.
|
||||
|
||||
For files exporting multiple utility functions, use the name that describes the responsibility of grouped utilities. For example, a file exporting math utilities should be named `math.ts`.
|
||||
|
||||
- Use `constants.ts` for files exporting constants.
|
||||
- Use `actions.ts` for files exporting Redux actions.
|
||||
- Use `reducers.ts` Redux reducers.
|
||||
- Use `*.test.ts(x)` for test files.
|
||||
|
||||
### Code organization
|
||||
|
||||
Organize your code in a directory that encloses feature code:
|
||||
|
||||
- Put Redux state and domain logic code in `state` directory (i.e. `features/my-feature/state/actions.ts`).
|
||||
- Put React components in `components` directory (i.e. `features/my-feature/components/ButtonPeopleDreamOf.tsx`).
|
||||
- Put test files next to the test subject.
|
||||
- Put containers (pages) in feature root (i.e. `features/my-feature/DashboardPage.tsx`).
|
||||
- Subcomponents can live in the component folders. Small component do not need their own folder.
|
||||
- Component SASS styles should live in the same folder as component code.
|
||||
|
||||
For code that needs to be used by external plugin:
|
||||
|
||||
- Put components and types in `@grafana/ui`.
|
||||
- Put data models and data utilities in `@grafana/data`.
|
||||
- Put runtime services interfaces in `@grafana/runtime`.
|
||||
|
||||
#### Exports
|
||||
|
||||
- Use named exports for all code you want to export from a file.
|
||||
- Use declaration exports (i.e. `export const foo = ...`).
|
||||
- Export only the code that is meant to be used outside the module.
|
||||
|
||||
### Comments
|
||||
|
||||
- Use [TSDoc](https://github.com/microsoft/tsdoc) comments to document your code.
|
||||
- Use [react-docgen](https://github.com/reactjs/react-docgen) comments (`/** ... */`) for props documentation.
|
||||
- Use inline comments for comments inside functions, classes etc.
|
||||
- Please try to follow the [code comment guidelines](./code-comments.md) when adding comments.
|
||||
|
||||
### Linting
|
||||
|
||||
Linting is performed using [@grafana/eslint-config](https://github.com/grafana/eslint-config-grafana).
|
||||
|
||||
## React
|
||||
|
||||
Use the following conventions when implementing React components:
|
||||
|
||||
### Props
|
||||
|
||||
##### Name callback props and handlers with an "on" prefix.
|
||||
|
||||
```tsx
|
||||
// bad
|
||||
handleChange = () => {
|
||||
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<MyComponent changed={this.handleChange} />
|
||||
);
|
||||
}
|
||||
|
||||
// good
|
||||
onChange = () => {
|
||||
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<MyComponent onChange={this.onChange} />
|
||||
);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
##### React Component definitions
|
||||
|
||||
```jsx
|
||||
// bad
|
||||
export class YourClass extends PureComponent { ... }
|
||||
|
||||
// good
|
||||
export class YourClass extends PureComponent<{},{}> { ... }
|
||||
```
|
||||
|
||||
##### React Component constructor
|
||||
|
||||
```typescript
|
||||
// bad
|
||||
constructor(props) {...}
|
||||
|
||||
// good
|
||||
constructor(props: Props) {...}
|
||||
```
|
||||
|
||||
##### React Component defaultProps
|
||||
|
||||
```typescript
|
||||
// bad
|
||||
static defaultProps = { ... }
|
||||
|
||||
// good
|
||||
static defaultProps: Partial<Props> = { ... }
|
||||
```
|
||||
|
||||
## State management
|
||||
|
||||
- Don't mutate state in reducers or thunks.
|
||||
- Use `createSlice`. See [Redux Toolkit](https://redux-toolkit.js.org/) for more details.
|
||||
- Use `reducerTester` to test reducers. See [Redux framework](redux.md) for more details.
|
||||
- Use state selectors to access state instead of accessing state directly.
|
||||
@@ -1,82 +0,0 @@
|
||||
# Redux framework
|
||||
|
||||
Grafana uses [Redux Toolkit](https://redux-toolkit.js.org/) to handle Redux boilerplate code.
|
||||
> Some of our Reducers are used by Angular and therefore state is to be considered as mutable for those reducers.
|
||||
|
||||
## Test functionality
|
||||
|
||||
### reducerTester
|
||||
|
||||
Fluent API that simplifies the testing of reducers
|
||||
|
||||
#### Usage
|
||||
|
||||
```typescript
|
||||
reducerTester()
|
||||
.givenReducer(someReducer, initialState)
|
||||
.whenActionIsDispatched(someAction('reducer tests'))
|
||||
.thenStateShouldEqual({ ...initialState, data: 'reducer tests' });
|
||||
```
|
||||
|
||||
#### Complex usage
|
||||
Sometimes you encounter a `resulting state` that contains properties that are hard to compare, such as `Dates`, but you still want to compare that other props in state are correct.
|
||||
|
||||
Then you can use `thenStatePredicateShouldEqual` function on `reducerTester` that will return the `resulting state` so that you can expect upon individual properties..
|
||||
|
||||
```typescript
|
||||
reducerTester()
|
||||
.givenReducer(someReducer, initialState)
|
||||
.whenActionIsDispatched(someAction('reducer tests'))
|
||||
.thenStatePredicateShouldEqual(resultingState => {
|
||||
expect(resultingState.data).toEqual('reducer tests');
|
||||
return true;
|
||||
});
|
||||
```
|
||||
|
||||
### thunkTester
|
||||
|
||||
Fluent API that simplifies the testing of thunks.
|
||||
|
||||
#### Usage
|
||||
|
||||
```typescript
|
||||
const dispatchedActions = await thunkTester(initialState)
|
||||
.givenThunk(someThunk)
|
||||
.whenThunkIsDispatched(arg1, arg2, arg3);
|
||||
|
||||
expect(dispatchedActions).toEqual([someAction('reducer tests')]);
|
||||
```
|
||||
|
||||
## Typing of connected props
|
||||
|
||||
It is possible to infer connected props automatically from `mapStateToProps` and `mapDispatchToProps` using a helper type `ConnectedProps` from Redux. For this to work the `connect` call has to be split into two parts.
|
||||
|
||||
```typescript
|
||||
import { connect, ConnectedProps } from 'react-redux'
|
||||
|
||||
const mapStateToProps = (state: StoreState) => {
|
||||
return {
|
||||
location: state.location,
|
||||
initDone: state.panelEditor.initDone,
|
||||
uiState: state.panelEditor.ui,
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = {
|
||||
updateLocation,
|
||||
initPanelEditor,
|
||||
panelEditorCleanUp,
|
||||
setDiscardChanges,
|
||||
updatePanelEditorUIState,
|
||||
updateTimeZoneForSession,
|
||||
};
|
||||
|
||||
const connector = connect(mapStateToProps, mapDispatchToProps);
|
||||
|
||||
type Props = OwnProps & ConnectedProps<typeof connector>;
|
||||
|
||||
class PanelEditorUnconnected extends PureComponent<Props> {};
|
||||
|
||||
export const PanelEditor = connector(PanelEditorUnconnected);
|
||||
```
|
||||
For more examples, refer to the [Redux docs](https://react-redux.js.org/using-react-redux/static-typing#inferring-the-connected-props-automatically).
|
||||
@@ -1,209 +0,0 @@
|
||||
# Storybook
|
||||
|
||||
[Storybook](https://storybook.js.org/) is a tool which we use to manage our design system and the components which are a part of it. Storybook consists of _stories:_ each story represents a component and a case in which it is used. To show a wide variety of use cases is good both documentation wise and for troubleshooting -- it might be possible to reproduce a bug for an edge case in a story.
|
||||
|
||||
Storybook is:
|
||||
|
||||
- A good way to publish our design system with its implementations
|
||||
- Used as a tool for documentation
|
||||
- Used for debugging and displaying edge cases
|
||||
|
||||
## How to create stories
|
||||
|
||||
Stories for a component should be placed next to the component file. The Storybook file requires the same name as the component file. For example, a story for `SomeComponent.tsx` will have the file name `SomeComponent.story.tsx`. If a story should be internal, not visible in production, name the file `SomeComponent.story.internal.tsx`.
|
||||
|
||||
### Writing stories
|
||||
|
||||
When writing stories, we use the [CSF format](https://storybook.js.org/docs/formats/component-story-format/). For more in-depth information on writing stories, see [Storybook’s documentation on writing stories](https://storybook.js.org/docs/basics/writing-stories/).
|
||||
|
||||
With the CSF format, the default export defines some general information about the stories in the file:
|
||||
|
||||
- `title`: Where the component is going to live in the hierarchy
|
||||
- `decorators`: A list which can contain wrappers or provide context, such as theming
|
||||
|
||||
```jsx
|
||||
// In MyComponent.story.tsx
|
||||
|
||||
import MyComponent from './MyComponent';
|
||||
|
||||
export default {
|
||||
title: 'General/MyComponent',
|
||||
component: MyComponent,
|
||||
decorators: [ ... ],
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
When it comes to writing the actual stories, you continue in the same file with named exports. The exports are turned into the story name.
|
||||
|
||||
```jsx
|
||||
// Will produce a story name “some story”
|
||||
export const someStory = () => <MyComponent />;
|
||||
```
|
||||
|
||||
If you want to write cover cases with different values for props, then using knobs is usually enough. You don’t need to create a new story. This will be covered further down.
|
||||
|
||||
### Categorization
|
||||
|
||||
We currently have these categories:
|
||||
|
||||
- **Docs Overview** - Guidelines and information regarding the design system
|
||||
- **Forms** - Components commonly used in forms such as different kind of inputs
|
||||
- **General** - Components which can be used in a lot of different places
|
||||
- **Visualizations** - Data visualizations
|
||||
- **Panel** - Components belonging to panels and panel editors
|
||||
|
||||
## Writing MDX documentation
|
||||
|
||||
An MDX file is basically a markdown file with the possibility to add jsx. These files are used by Storybook to create a “docs” tab.
|
||||
|
||||
### Link the MDX file to a component’s stories
|
||||
|
||||
To link a component’s stories with an MDX file you have to do this:
|
||||
|
||||
```jsx
|
||||
// In TabsBar.story.tsx
|
||||
|
||||
import { TabsBar } from './TabsBar';
|
||||
|
||||
// Import the MDX file
|
||||
import mdx from './TabsBar.mdx';
|
||||
|
||||
export default {
|
||||
title: 'General/Tabs/TabsBar',
|
||||
component: TabsBar,
|
||||
parameters: {
|
||||
docs: {
|
||||
// This is the reference required for the MDX file
|
||||
page: mdx,
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### MDX file structure
|
||||
|
||||
There are some things that the MDX file should contain:
|
||||
|
||||
- When and why the component should be used
|
||||
- Best practices - dos and don’ts for the component
|
||||
- Usage examples with code. It is possible to use the `Preview` element to show live examples in MDX
|
||||
- Props table. This can be generated by doing the following:
|
||||
|
||||
```jsx
|
||||
// In MyComponent.mdx
|
||||
|
||||
import { Props } from '@storybook/addon-docs/blocks';
|
||||
import { MyComponent } from './MyComponent';
|
||||
|
||||
<Props of={MyComponent} />;
|
||||
```
|
||||
|
||||
### MDX file without a relationship to a component
|
||||
|
||||
An MDX file can exist by itself without any connection to a story. This can be good for writing things such as a general guidelines page. Two things are required for this to work:
|
||||
|
||||
- The file needs to be named `*.story.mdx`
|
||||
- A `Meta` tag must exist that says where in the hierarchy the component lives. It can look like this:
|
||||
|
||||
```jsx
|
||||
<Meta title="Docs Overview/Color Palettes"/>
|
||||
|
||||
# Guidelines for using colors
|
||||
|
||||
...
|
||||
|
||||
```
|
||||
|
||||
You can add parameters to the Meta tag. This example shows how to hide the tools:
|
||||
|
||||
```jsx
|
||||
<Meta title="Docs Overview/Color Palettes" parameters={{ options: { isToolshown: false }}}/>
|
||||
|
||||
# Guidelines for using colors
|
||||
|
||||
...
|
||||
|
||||
```
|
||||
|
||||
## Documenting component properties
|
||||
|
||||
A quick way to get an overview of what a component does is by looking at its properties. That's why it is important that we document these in a good way.
|
||||
|
||||
### Comments
|
||||
|
||||
When writing the props interface for a component, it is possible to add a comment to that specific property, which will end up in the Props table in the MDX file. The comments are generated by [react-docgen](https://github.com/reactjs/react-docgen) and are formatted by writing `/** */`.
|
||||
|
||||
```jsx
|
||||
interface MyProps {
|
||||
/** Sets the initial values, which are overridden when the query returns a value*/
|
||||
defaultValues: Array<T>;
|
||||
}
|
||||
```
|
||||
|
||||
### Controls
|
||||
|
||||
The [controls addon](https://storybook.js.org/docs/react/essentials/controls) provides a way to interact with a component's properties dynamically and requires much less code than knobs. We're deprecating knobs in favor of using controls.
|
||||
|
||||
#### Migrating a story from Knobs to Controls
|
||||
|
||||
As a test, we migrated the [button story](https://github.com/grafana/grafana/blob/main/packages/grafana-ui/src/components/Button/Button.story.tsx). Here's the guide on how to migrate a story to controls.
|
||||
|
||||
1. Remove the `@storybook/addon-knobs` dependency.
|
||||
2. Import the Story type from `@storybook/react`
|
||||
|
||||
`import { Story } from @storybook/react`
|
||||
|
||||
3. Import the props interface from the component you're working on (these must be exported in the component).
|
||||
|
||||
`import { Props } from './Component'`
|
||||
|
||||
4. Add the Story type to all stories in the file, then replace the props sent to the component
|
||||
and remove any knobs.
|
||||
|
||||
Before
|
||||
|
||||
```tsx
|
||||
export const Simple = () => {
|
||||
const prop1 = text('Prop1', 'Example text');
|
||||
const prop2 = select('Prop2', ['option1', 'option2'], 'option1');
|
||||
|
||||
return <Component prop1={prop1} prop2={prop2} />;
|
||||
};
|
||||
```
|
||||
|
||||
After
|
||||
|
||||
```tsx
|
||||
export const Simple: Story<Props> = ({ prop1, prop2 }) => {
|
||||
return <Component prop1={prop1} prop2={prop2} />;
|
||||
};
|
||||
```
|
||||
|
||||
5. Add default props (or args in Storybook language).
|
||||
|
||||
```tsx
|
||||
Simple.args = {
|
||||
prop1: 'Example text',
|
||||
prop2: 'option 1',
|
||||
};
|
||||
```
|
||||
|
||||
6. If the component has advanced props type (ie. other than string, number, boolean), you need to
|
||||
specify these in an `argTypes`. This is done in the default export of the story.
|
||||
|
||||
```tsx
|
||||
export default {
|
||||
title: 'Component/Component',
|
||||
component: Component,
|
||||
argTypes: {
|
||||
prop2: { control: { type: 'select', options: ['option1', 'option2'] } },
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Best practices
|
||||
|
||||
- When creating a new component or writing documentation for an existing one, always cover the basic use case it was intended for with a code example.
|
||||
- Use stories and knobs to create edge cases. If you are trying to solve a bug, try to reproduce it with a story.
|
||||
- Do not create stories in the MDX, always create them in the `*.story.tsx` file.
|
||||
@@ -1,117 +0,0 @@
|
||||
# Styling Grafana
|
||||
|
||||
[Emotion](https://emotion.sh/docs/introduction) is our default-to-be approach to styling React components. It provides a way for styles to be a consequence of properties and state of a component.
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic styling
|
||||
|
||||
For styling components, use [Emotion's `css` function](https://emotion.sh/docs/emotion#css).
|
||||
|
||||
```tsx
|
||||
import React from 'react';
|
||||
import { css } from '@emotion/css';
|
||||
|
||||
const ComponentA = () => (
|
||||
<div
|
||||
className={css`
|
||||
background: red;
|
||||
`}
|
||||
>
|
||||
As red as you can get
|
||||
</div>
|
||||
);
|
||||
```
|
||||
|
||||
### Styling with theme
|
||||
|
||||
To access the theme in your styles, use the `useStyles` hook. It provides basic memoization and access to the theme object.
|
||||
|
||||
> Please remember to put `getStyles` function at the end of the file!
|
||||
|
||||
```tsx
|
||||
import React, { FC } from 'react';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import { useStyles } from '@grafana/ui';
|
||||
import { css } from '@emotion/css';
|
||||
|
||||
const Foo: FC<FooProps> = () => {
|
||||
const styles = useStyles(getStyles);
|
||||
|
||||
// Use styles with classNames
|
||||
return <div className={styles}>...</div>;
|
||||
};
|
||||
|
||||
const getStyles = (theme: GrafanaTheme) => css`
|
||||
padding: ${theme.spacing.md};
|
||||
`;
|
||||
```
|
||||
|
||||
### Styling complex components
|
||||
|
||||
In more complex cases, especially when you need to style multiple DOM elements in one component, or when using styles that depend on properties and/or state, you should create a helper function that returns an object of styles. This function should also be wrapped in the `stylesFactory` helper function, which will provide basic memoization.
|
||||
|
||||
Let's say you need to style a component that has a different background depending on the `isActive` property :
|
||||
|
||||
```tsx
|
||||
import React from 'react';
|
||||
import { css } from '@emotion/css';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import { selectThemeVariant, stylesFactory, useTheme } from '@grafana/ui';
|
||||
|
||||
interface ComponentAProps {
|
||||
isActive: boolean;
|
||||
}
|
||||
|
||||
const ComponentA: React.FC<ComponentAProps> = ({ isActive }) => {
|
||||
const theme = useTheme();
|
||||
const styles = getStyles(theme, isActive);
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
As red as you can get
|
||||
<i className={styles.icon} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// Mind, that you can pass multiple arguments, theme included
|
||||
const getStyles = stylesFactory((theme: GrafanaTheme, isActive: boolean) => {
|
||||
const backgroundColor = isActive ? theme.colors.red : theme.colors.blue;
|
||||
|
||||
return {
|
||||
wrapper: css`
|
||||
background: ${backgroundColor};
|
||||
`,
|
||||
icon: css`
|
||||
font-size: ${theme.typography.size.sm};
|
||||
`,
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
For more information about themes at Grafana please see the [themes guide](./themes.md).
|
||||
|
||||
### Composing class names
|
||||
|
||||
For class composition, use [Emotion's `cx` function](https://emotion.sh/docs/emotion#cx).
|
||||
|
||||
```tsx
|
||||
import React from 'react';
|
||||
import { css, cx } from '@emotion/css';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const ComponentA: React.FC<Props> = ({ className }) => {
|
||||
const finalClassName = cx(
|
||||
className,
|
||||
css`
|
||||
background: red;
|
||||
`
|
||||
);
|
||||
|
||||
return <div className={finalClassName}>As red as you can ge</div>;
|
||||
};
|
||||
```
|
||||
@@ -1,151 +0,0 @@
|
||||
# Theming Grafana
|
||||
|
||||
## Overview
|
||||
|
||||
**Themes are implemented in Typescript.** That's because our goal is to share variables between Grafana TypeScript and [Sass](https://sass-lang.com/) code. Theme definitions are located in the following files:
|
||||
|
||||
- [packages/grafana-ui/src/themes/dark.ts](../../packages/grafana-ui/src/themes/dark.ts)
|
||||
- [packages/grafana-ui/src/themes/default.ts](../../packages/grafana-ui/src/themes/default.ts)
|
||||
- [packages/grafana-ui/src/themes/light.ts](../../packages/grafana-ui/src/themes/light.ts)
|
||||
|
||||
The `default.ts` file holds common variables like typography and spacing definitions, while `[light|dark].ts` primarily specify colors used in themes.
|
||||
|
||||
## Usage
|
||||
|
||||
This section provides usage guidelines.
|
||||
|
||||
### Using themes in React components
|
||||
|
||||
Here's how to use Grafana themes in React components.
|
||||
|
||||
#### useStyles hook
|
||||
|
||||
`useStyles` memoizes the function and provides access to the theme.
|
||||
|
||||
```tsx
|
||||
import React, { FC } from 'react';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import { useStyles } from '@grafana/ui';
|
||||
import { css } from '@emotion/css';
|
||||
|
||||
const getComponentStyles = (theme: GrafanaTheme) => css`
|
||||
padding: ${theme.spacing.md};
|
||||
`;
|
||||
|
||||
const Foo: FC<FooProps> = () => {
|
||||
const styles = useStyles(getComponentsStyles);
|
||||
|
||||
// Use styles with className
|
||||
};
|
||||
```
|
||||
|
||||
#### Get the theme object
|
||||
|
||||
```tsx
|
||||
import React, { FC } from 'react';
|
||||
import { useTheme } from '@grafana/ui';
|
||||
|
||||
const Foo: FC<FooProps> = () => {
|
||||
const theme = useTheme();
|
||||
|
||||
// Your component has access to the theme variables now
|
||||
};
|
||||
```
|
||||
|
||||
#### Using `ThemeContext` directly
|
||||
|
||||
```tsx
|
||||
import { ThemeContext } from '@grafana/ui';
|
||||
|
||||
<ThemeContext.Consumer>{(theme) => <Foo theme={theme} />}</ThemeContext.Consumer>;
|
||||
```
|
||||
|
||||
#### Using `withTheme` higher-order component (HOC)
|
||||
|
||||
With this method your component will be automatically wrapped in `ThemeContext.Consumer` and provided with current theme via `theme` prop. Components used with `withTheme` must implement the `Themeable` interface.
|
||||
|
||||
```ts
|
||||
import { ThemeContext, Themeable } from '@grafana/ui';
|
||||
|
||||
interface FooProps extends Themeable {}
|
||||
|
||||
const Foo: React.FunctionComponent<FooProps> = () => ...
|
||||
|
||||
export default withTheme(Foo);
|
||||
```
|
||||
|
||||
### Test components that use `ThemeContext`
|
||||
|
||||
When implementing snapshot tests for components that use the `withTheme` HOC, the snapshot will contain the entire theme object. Any change to the theme renders the snapshot outdated.
|
||||
|
||||
To make your snapshot theme independent, use the `mockThemeContext` helper function:
|
||||
|
||||
```tsx
|
||||
import { mockThemeContext } from '@grafana/ui';
|
||||
import { MyComponent } from './MyComponent';
|
||||
|
||||
describe('MyComponent', () => {
|
||||
let restoreThemeContext;
|
||||
|
||||
beforeAll(() => {
|
||||
// Create ThemeContext mock before any snapshot test is executed
|
||||
restoreThemeContext = mockThemeContext({ type: GrafanaThemeType.Dark });
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
// Make sure the theme is restored after snapshot tests are performed
|
||||
restoreThemeContext();
|
||||
});
|
||||
|
||||
it('renders correctly', () => {
|
||||
const wrapper = mount(<MyComponent />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## FAQ
|
||||
|
||||
This section provides insight into frequently-asked questions.
|
||||
|
||||
### How can I modify Sass variable files?
|
||||
|
||||
**If possible, migrate styles to Emotion**
|
||||
|
||||
> For the following to apply you need to run `yarn dev` task.
|
||||
|
||||
`[_variables|_variables.dark|_variables.light].generated.scss` files are the ones that are referenced in the main Sass files for Sass variables to be available. **These files are automatically generated and should never be modified by hand!**
|
||||
|
||||
#### If you need to modify a _Sass variable value_ you need to modify the corresponding Typescript file that is the source of the variables:
|
||||
|
||||
- `_variables.generated.scss` - modify `grafana-ui/src/themes/default.ts`
|
||||
- `_variables.light.generated.scss` - modify `grafana-ui/src/themes/light.ts`
|
||||
- `_variables.dark.generated.scss` - modify `grafana-ui/src/themes/dark.ts`
|
||||
|
||||
#### If you need to _add new variable_ to Sass variables you need to modify corresponding template file:
|
||||
|
||||
- `_variables.generated.scss` - modify `grafana-ui/src/themes/_variables.scss.tmpl.ts`
|
||||
- `_variables.light.generated.scss` - modify `grafana-ui/src/themes/_variables.light.scss.tmpl.ts`
|
||||
- `_variables.dark.generated.scss` - modify `grafana-ui/src/themes/_variables.dark.scss.tmpl.ts`
|
||||
|
||||
## Limitations
|
||||
|
||||
This section describes limitations with Grafana's theming system.
|
||||
|
||||
### You must ensure `ThemeContext` provider is available in a React tree
|
||||
|
||||
By default all react2angular directives have `ThemeContext.Provider` ensured. But, there are cases where we create another React tree via `ReactDOM.render`. This happens in the case of graph legend rendering and the `ReactContainer` directive. In such cases theme consumption will fail. To make sure theme context is available in such cases, you need to wrap your rendered component with ThemeContext.Provider using the `provideTheme` function:
|
||||
|
||||
```ts
|
||||
// graph.ts
|
||||
import { provideTheme } from 'app/core/utils/ConfigProvider';
|
||||
|
||||
// Create component with ThemeContext.Provider first.
|
||||
// Otherwise React will create new components every time it renders!
|
||||
const LegendWithThemeProvider = provideTheme(Legend);
|
||||
|
||||
const legendReactElem = React.createElement(LegendWithThemeProvider, legendProps);
|
||||
ReactDOM.render(legendReactElem, this.legendElem, () => this.renderPanel());
|
||||
```
|
||||
|
||||
`provideTheme` makes current theme available via ThemeContext by checking if user has `lightTheme` set in her boot data.
|
||||
@@ -1,57 +0,0 @@
|
||||
# Templates
|
||||
|
||||
Templates are both a starting point and an instruction manual for writing something new. They are intended to make life easier by providing a jumping-off point, something besides a blank page to start from. They are not intended to be a limitation. If the template does not work perfectly for your use case, you can adjust or change it. We will work it out in code review.
|
||||
|
||||
## Create a template
|
||||
|
||||
Feel free to add templates to the `templates` folder. Try to make them as generic as possible and include clear instructions for when and how to use the template. Assume that the template user is a brand new contributor and write accordingly.
|
||||
|
||||
## Use a template
|
||||
|
||||
1. Read the template. Make sure you understand what it is for and how it is intended to be used.
|
||||
1. Copy and rename the template. Move it to where you actually need it.
|
||||
You might also want to copy the content of the template and paste it into a different file. This is acceptable use.
|
||||
1. Replace the template content with your own. Delete whatever is unnecessary.
|
||||
|
||||
## Documentation templates
|
||||
|
||||
In an ideal world, each topic will correspond to an information *type* ([task](doc-task-template.md), [reference](doc-reference-template.md), [concept](doc-concept-template.md)) and contain only that type of information.
|
||||
|
||||
However, this is not always practical. For example, you have a series of short topics, you can group them into one topic.
|
||||
|
||||
Try to *chunk* your content. This means you should organize the document so that the same kinds of content are grouped together.
|
||||
|
||||
### Chunking example
|
||||
|
||||
If I was writing content for a site called *Doggie handbook*, I might organize it like this.
|
||||
|
||||
**Concept**
|
||||
- What a dog is
|
||||
- Brief history of dogs
|
||||
- Why you might want a dog
|
||||
- Tasks dogs can be trained to do
|
||||
|
||||
**Tasks**
|
||||
- Feed the dog
|
||||
- Groom the dog
|
||||
- Train the dog
|
||||
|
||||
**Reference**
|
||||
- List of dog equipment you will need
|
||||
- Table of breeds that includes breed name, size range, short or long hair, and type of dog
|
||||
|
||||
### Audience
|
||||
|
||||
Write for an audience that is computer literate and has general technical knowledge, but is not necessarily familiar with Grafana or the finer points of observability.
|
||||
|
||||
Pretend you are explaining your topic to a brand new Grafana user or developer.
|
||||
|
||||
### Self-contained
|
||||
|
||||
Thanks to search engines, every page in the documentation might be a reader's entry point. This means that each page needs to be self-contained and make sense on its own. The reader should not need to read other topics in order to perform the task or understand the concept.
|
||||
|
||||
However, try to be helpful and link to related information. Using the *Doggie handbook* example, the concept topic that explains what dogs can be trained to do might link to the Train the dog task.
|
||||
|
||||
## Code templates
|
||||
|
||||
This is a placeholder for future templates.
|
||||
@@ -1,42 +0,0 @@
|
||||
DELETE THIS LINE: If draft = false, then the document will not be built in the doc site. If the date is earlier than the build date, than the document will not show in the build site. Use these settings to control whether future content is shown in the doc site.
|
||||
+++
|
||||
draft = "false"
|
||||
date = "yyyy-mm-dd"
|
||||
title = "Title in sentence case"
|
||||
description = "Description in title case"
|
||||
keywords = ["grafana", "enter", "keywords", "here"]
|
||||
type = "docs"
|
||||
[menu.docs]
|
||||
name = "Name of topic"
|
||||
identifier = "identifier"
|
||||
parent = "menu parent"
|
||||
weight = 100
|
||||
+++
|
||||
|
||||
# Concept
|
||||
|
||||
The title of the concept topic will generally be a noun or a gerund. Examples include Templates, Templating, Dashboards, and panels.
|
||||
|
||||
Concepts are topic types for any information that doesn't involve task lists or reference information. Ideally you use concept elements to explain concepts, ideas, overviews, workflows, and the like. In the intro section, this first paragraph or two, you should explain to the user what to expect in this topic or section.
|
||||
|
||||
[Permissions overview](https://grafana.com/docs/grafana/latest/permissions/overview/) is an example of a concept topic.
|
||||
|
||||
## Idea
|
||||
|
||||
Concept topics or sections explain *what* and *why*. They do not explain *how*. If you are a new user, you might look for concept information to learn about what Grafana is, why it might be useful to you, and what the general workflow is.
|
||||
|
||||
## Workflow
|
||||
|
||||
Continuing the example in the previous section, here is a sample Grafana workflow.
|
||||
|
||||
1. Install Grafana. <link to task for installing Grafana>
|
||||
1. Set up data sources. <link to data sources concept topic, which links to data source task topics>
|
||||
1. Create panels. <link to panel concept topic, which links to tasks>
|
||||
1. Create dashboards. <link to panel concept topic, which links to tasks>
|
||||
1. Enter queries. <link to query editor concept topic>
|
||||
1. Add users. <link to user management concept topic, which links to tasks>
|
||||
1. Create playlists. <link to Playlist topic that contains concept information and tasks>
|
||||
|
||||
## Next steps
|
||||
|
||||
Concept tasks often link to related information, including *tasks* related to the concept and *reference* topics related to the concept.
|
||||
@@ -1,75 +0,0 @@
|
||||
DELETE THIS LINE: If draft = false, then the document will not be built in the doc site. If the date is earlier than the build date, than the document will not show in the build site. Use these settings to control whether future content is shown in the doc site.
|
||||
+++
|
||||
draft = "false"
|
||||
date = "yyyy-mm-dd"
|
||||
title = "Title in sentence case"
|
||||
description = "Description in title case"
|
||||
keywords = ["grafana", "enter", "keywords", "here"]
|
||||
type = "docs"
|
||||
[menu.docs]
|
||||
name = "Name of topic"
|
||||
identifier = "identifier"
|
||||
parent = "menu parent"
|
||||
weight = 100
|
||||
+++
|
||||
|
||||
# Reference
|
||||
|
||||
The *reference* topic type is for storing reference information, such as extensive tables, lists, or other information that is used as support for a task. Reference topics are also designed for API information.
|
||||
|
||||
Often reference topics are linked from *task* topics, because they contain information the user needs in order to perform a task.
|
||||
|
||||
[Grafana CLI](https://grafana.com/docs/grafana/latest/administration/cli/) is one example of a reference topic.
|
||||
|
||||
## Lists
|
||||
|
||||
Lists of commands or parameters are often organized in reference topics. The information you need to present will dictate the format.
|
||||
|
||||
- They might
|
||||
- be in
|
||||
- unordered lists.
|
||||
|
||||
[Configuration](https://grafana.com/docs/grafana/latest/installation/configuration/) is an example of lists.
|
||||
|
||||
## Tables
|
||||
|
||||
If you have a large list of things to store in a table, then you are probably dealing with reference information. Hugo accepts either tables in Markdown or in HTML format, so use whichever is easier for you.
|
||||
|
||||
The [Glossary](https://grafana.com/docs/grafana/latest/guides/glossary/) provides an example of reference data in a table.
|
||||
|
||||
### Empty markdown table
|
||||
|
||||
While you might not need a heading for each table, headings are a good way to chunk information if you have several tables. They also make the content easy to skim. Use headings or intro paragraphs like this one to explain to the reader what the information in the table is used for.
|
||||
|
||||
| | | | | | |
|
||||
|:---|:---|:--:|:--:|---:|---:|
|
||||
| | | | | | |
|
||||
| | | | | | |
|
||||
| | | | | | |
|
||||
| | | | | | |
|
||||
|
||||
### Empty HTML table
|
||||
|
||||
And here is intro text, similar to the paragraph in the previous section. Do not add local styling to the table. The website CSS will take care of that for you.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Firstname</th>
|
||||
<th>Lastname</th>
|
||||
<th>Age</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Jill</td>
|
||||
<td>Smith</td>
|
||||
<td>50</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Eve</td>
|
||||
<td>Jackson</td>
|
||||
<td>94</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## API documentation
|
||||
|
||||
API documentation is always a reference topic rather than a task topic, but it has its own rules.
|
||||
@@ -1,57 +0,0 @@
|
||||
+++
|
||||
draft = "false"
|
||||
date = "yyyy-mm-dd"
|
||||
title = "Title in sentence case"
|
||||
description = "Description in title case"
|
||||
keywords = ["grafana", "enter", "keywords", "here"]
|
||||
type = "docs"
|
||||
[menu.docs]
|
||||
name = "Name of topic"
|
||||
identifier = "identifier"
|
||||
parent = "menu parent"
|
||||
weight = 100
|
||||
+++
|
||||
|
||||
# Task
|
||||
|
||||
A *task* topic is intended for a procedure that describes how to accomplish a task. It lists a series of steps that users follow to produce an intended outcome. It tells the reader *how* to do something. [Install Grafana plugins](https://grafana.com/docs/grafana/latest/plugins/installation/) and [Playlist](https://grafana.com/docs/grafana/latest/reference/playlist/) are examples of task topics. Playlist includes a small amount of concept information in the introduction, which is appropriate.
|
||||
|
||||
Always include an introduction of a short paragraph or two to explain what the task is for, perhaps give the reader an idea of what the outcome will be.
|
||||
|
||||
In most cases, each topic should only contain one task. If you have several very short, related tasks, then you might combine them into one topic.
|
||||
|
||||
In the case of a long task, then you probably won't need any headings except for the h1 at the top of the page.
|
||||
|
||||
1. Start with step one.
|
||||
1. Use second-person imperative tense.
|
||||
1. Basically, "You, do this" with every sentence.
|
||||
1. Do not use the third-person "user" for steps you want the reader ("you") to perform.
|
||||
1. Write steps that contain one action, possibly two related actions, such as copy and paste a thing or save and quit the program.
|
||||
If a sentence is not telling the reader to do something, then it is not a step. You can use nested images or paragraphs like this one to add information if necessary.
|
||||
|
||||
In many cases, you should tell the reader what the outcome should be so that they know when they are done.
|
||||
|
||||
## One-step task
|
||||
|
||||
Some tasks are so short, they only contain one step.
|
||||
|
||||
Write one-step tasks as simple sentences, not as unordered lists or numbered lists.
|
||||
|
||||
## Short task
|
||||
|
||||
Short tasks can be grouped. How short constitutes "short" is a judgment call based on number of steps and how long individual steps are.
|
||||
|
||||
1. Use your judgment.
|
||||
1. Ask your coworkers or someone on the Comm team for advice if you aren't sure.
|
||||
|
||||
## Next steps
|
||||
|
||||
If the task you are writing leads naturally to one or more other tasks, then include links after the task to help the reader figure out where to go next.
|
||||
|
||||
Thanks to internet search engines, every page in the documentation could be page one. Pretend you are explaining your task to a new Grafana user who just walked in off the street.
|
||||
|
||||
## Testing
|
||||
|
||||
It is a good practice to have someone else test the task you have written. If they can successfully complete the task using *only* what the steps you have written, not guessing or using their inherent knowledge, then your task has passed the test. However, it is very common to find you have skipped steps, because *you* are very familiar with Grafana and the topic you are explaining.
|
||||
|
||||
New users or people from other teams are very helpful for these tests.
|
||||
@@ -1,32 +0,0 @@
|
||||
# Triage issues
|
||||
|
||||
Triage helps ensure that issues resolve quickly by:
|
||||
|
||||
- Ensuring the issue's intent and purpose is conveyed precisely. This is necessary because it can be difficult for an issue to explain how an end user experiences a problem and what actions they took.
|
||||
- Giving a contributor the information they need before they commit to resolving an issue.
|
||||
- Lowering the issue count by preventing duplicate issues.
|
||||
- Streamlining the development process by preventing duplicate discussions.
|
||||
|
||||
This document gives you some ideas on what you can do to help. For more information, read more about [how the core Grafana team triage issues](/ISSUE_TRIAGE.md).
|
||||
|
||||
## Improve issues
|
||||
|
||||
Improve issues by suggesting improvements to the title and description. If you think an issue has formatting issues, bad language, or grammatical errors, post a comment to let the author and maintainers know.
|
||||
|
||||
## Report resolved issues
|
||||
|
||||
If you think an issue has been resolved, or is no longer relevant, suggest us to close it. Add a comment on the issue, where you explain the reason it should be closed. Make sure to include any related issues and pull requests.
|
||||
|
||||
## Investigate issues
|
||||
|
||||
Investigate issues that we haven't been able to reproduce yet. In some cases, there are many combinations of panels, dashboards, and data sources that make it difficult for us to reproduce certain issues. Help us by adding more information.
|
||||
|
||||
## Vote on issues
|
||||
|
||||
Use [GitHub reactions](https://help.github.com/en/articles/about-conversations-on-github#reacting-to-ideas-in-comments) to let us know what's important to you. Vote on bugs if you've experienced the same problem. **Don't vote, or react, by commenting on the issue.**
|
||||
|
||||
Read more about [how we prioritize issues](/ISSUE_TRIAGE.md#4-prioritization-of-issues).
|
||||
|
||||
## Report duplicates
|
||||
|
||||
If you find two issues that describe the same thing, add a comment in one of the issues, with a reference (`#<issue number>`) to the other. Explain why you think the issue is duplicated.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user