mirror of
https://github.com/grafana/grafana.git
synced 2025-12-28 16:43:47 +08:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e25cfc7fc2 | ||
|
|
0988471a16 | ||
|
|
3c152dc5bd | ||
|
|
92c1b1e4c6 | ||
|
|
84669d2213 | ||
|
|
1ff6fa9424 | ||
|
|
2f4a097e53 |
14
.babelrc
Normal file
14
.babelrc
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"presets": [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"targets": {
|
||||
"browsers": "last 3 versions"
|
||||
},
|
||||
"useBuiltIns": "entry",
|
||||
"modules": "false",
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
12
.bingo/.gitignore
vendored
12
.bingo/.gitignore
vendored
@@ -1,12 +0,0 @@
|
||||
|
||||
# Ignore everything
|
||||
*
|
||||
|
||||
# But not these files:
|
||||
!.gitignore
|
||||
!*.mod
|
||||
!README.md
|
||||
!Variables.mk
|
||||
!variables.env
|
||||
|
||||
*tmp.mod
|
||||
@@ -1,14 +0,0 @@
|
||||
# Project Development Dependencies.
|
||||
|
||||
This is directory which stores Go modules with pinned buildable package that is used within this repository, managed by https://github.com/bwplotka/bingo.
|
||||
|
||||
- Run `bingo get` to install all tools having each own module file in this directory.
|
||||
- Run `bingo get <tool>` to install <tool> that have own module file in this directory.
|
||||
- For Makefile: Make sure to put `include .bingo/Variables.mk` in your Makefile, then use $(<upper case tool name>) variable where <tool> is the .bingo/<tool>.mod.
|
||||
- For shell: Run `source .bingo/variables.env` to source all environment variable for each tool.
|
||||
- For go: Import `.bingo/variables.go` to for variable names.
|
||||
- See https://github.com/bwplotka/bingo or -h on how to add, remove or change binaries dependencies.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Go 1.14+
|
||||
@@ -1,31 +0,0 @@
|
||||
# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.5.1. DO NOT EDIT.
|
||||
# All tools are designed to be build inside $GOBIN.
|
||||
BINGO_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
|
||||
GOPATH ?= $(shell go env GOPATH)
|
||||
GOBIN ?= $(firstword $(subst :, ,${GOPATH}))/bin
|
||||
GO ?= $(shell which go)
|
||||
|
||||
# Below generated variables ensure that every time a tool under each variable is invoked, the correct version
|
||||
# will be used; reinstalling only if needed.
|
||||
# For example for drone variable:
|
||||
#
|
||||
# In your main Makefile (for non array binaries):
|
||||
#
|
||||
#include .bingo/Variables.mk # Assuming -dir was set to .bingo .
|
||||
#
|
||||
#command: $(DRONE)
|
||||
# @echo "Running drone"
|
||||
# @$(DRONE) <flags/args..>
|
||||
#
|
||||
DRONE := $(GOBIN)/drone-v1.4.0
|
||||
$(DRONE): $(BINGO_DIR)/drone.mod
|
||||
@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
|
||||
@echo "(re)installing $(GOBIN)/drone-v1.4.0"
|
||||
@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=drone.mod -o=$(GOBIN)/drone-v1.4.0 "github.com/drone/drone-cli/drone"
|
||||
|
||||
WIRE := $(GOBIN)/wire-v0.5.0
|
||||
$(WIRE): $(BINGO_DIR)/wire.mod
|
||||
@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
|
||||
@echo "(re)installing $(GOBIN)/wire-v0.5.0"
|
||||
@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=wire.mod -o=$(GOBIN)/wire-v0.5.0 "github.com/google/wire/cmd/wire"
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT
|
||||
|
||||
go 1.17
|
||||
|
||||
replace github.com/docker/docker => github.com/docker/engine v17.12.0-ce-rc1.0.20200309214505-aa6a9891b09c+incompatible
|
||||
|
||||
require github.com/drone/drone-cli v1.4.0 // drone
|
||||
@@ -1 +0,0 @@
|
||||
module _ // Fake go.mod auto-created by 'bingo' for go -moddir compatibility with non-Go projects. Commit this file, together with other .mod files.
|
||||
@@ -1,14 +0,0 @@
|
||||
# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.5.1. DO NOT EDIT.
|
||||
# All tools are designed to be build inside $GOBIN.
|
||||
# Those variables will work only until 'bingo get' was invoked, or if tools were installed via Makefile's Variables.mk.
|
||||
GOBIN=${GOBIN:=$(go env GOBIN)}
|
||||
|
||||
if [ -z "$GOBIN" ]; then
|
||||
GOBIN="$(go env GOPATH)/bin"
|
||||
fi
|
||||
|
||||
|
||||
DRONE="${GOBIN}/drone-v1.4.0"
|
||||
|
||||
WIRE="${GOBIN}/wire-v0.5.0"
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT
|
||||
|
||||
go 1.16
|
||||
|
||||
require github.com/google/wire v0.5.0 // cmd/wire
|
||||
@@ -1,6 +1,5 @@
|
||||
[run]
|
||||
init_cmds = [
|
||||
["make", "gen-go"],
|
||||
["go", "run", "build.go", "-dev", "build-cli"],
|
||||
["go", "run", "build.go", "-dev", "build-server"],
|
||||
["./bin/grafana-server", "-packaging=dev", "cfg:app_mode=development"]
|
||||
|
||||
@@ -1,15 +1,4 @@
|
||||
[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%,
|
||||
Chrome > 20
|
||||
last 4 versions,
|
||||
Firefox ESR
|
||||
|
||||
1214
.circleci/config.yml
1214
.circleci/config.yml
File diff suppressed because it is too large
Load Diff
@@ -12,14 +12,7 @@ Dockerfile
|
||||
docs
|
||||
dump.rdb
|
||||
node_modules
|
||||
**/node_modules
|
||||
/local
|
||||
/tmp
|
||||
*.yml
|
||||
!.yarnrc.yml
|
||||
*.md
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/releases
|
||||
!.yarn/plugins
|
||||
!.yarn/versions
|
||||
!.yarn/cache
|
||||
|
||||
19
.drone.star
19
.drone.star
@@ -1,17 +1,8 @@
|
||||
# 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/drone/pipelines/pr.star', 'pr_pipelines')
|
||||
load('scripts/drone/pipelines/main.star', 'main_pipelines')
|
||||
load('scripts/drone/pipelines/release.star', 'release_pipelines', 'test_release_pipelines')
|
||||
load('scripts/drone/version.star', 'version_branch_pipelines')
|
||||
load('scripts/drone/pipelines/cron.star', 'cronjobs')
|
||||
load('scripts/drone/vault.star', 'secrets')
|
||||
load('scripts/pr.star', 'pr_pipelines')
|
||||
load('scripts/master.star', 'master_pipelines')
|
||||
load('scripts/release.star', 'release_pipelines', 'test_release_pipelines')
|
||||
|
||||
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()
|
||||
return pr_pipelines(edition=edition) + master_pipelines(edition=edition) + release_pipelines() + \
|
||||
test_release_pipelines()
|
||||
|
||||
5404
.drone.yml
5404
.drone.yml
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,3 @@ vendor
|
||||
devenv
|
||||
data
|
||||
dist
|
||||
e2e/tmp
|
||||
public/lib/monaco
|
||||
deployment_tools_config.json
|
||||
|
||||
17
.eslintrc
17
.eslintrc
@@ -1,28 +1,13 @@
|
||||
{
|
||||
"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}"],
|
||||
"files": ["packages/grafana-ui/**/*/!(*.story).{ts,tsx}", "public/app/**/*.{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
|
||||
138
.github/CODEOWNERS
vendored
138
.github/CODEOWNERS
vendored
@@ -11,123 +11,42 @@
|
||||
# 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: Jita Chatterjee
|
||||
/docs/ @grafana/docs-squad @pkolyvas
|
||||
/contribute/ @marcusolsson @grafana/docs-squad @pkolyvas
|
||||
/docs/sources/developers/plugins/ @marcusolsson @grafana/docs-squad @grafana/plugins-platform
|
||||
/docs/sources/developers/plugins/backend @marcusolsson @grafana/docs-squad @grafana/plugins-platform-backend
|
||||
/docs/sources/enterprise/ @osg-grafana @grafana/docs-squad
|
||||
# Documentation owner: Diana Payton
|
||||
/docs/ @oddlittlebird @achatterjee-grafana
|
||||
/contribute/ @oddlittlebird @marcusolsson @achatterjee-grafana
|
||||
/docs/sources/developers/plugins/ @marcusolsson
|
||||
|
||||
# Backend code
|
||||
*.go @grafana/backend-platform
|
||||
go.mod @grafana/backend-platform
|
||||
go.sum @grafana/backend-platform
|
||||
/.bingo @grafana/backend-platform
|
||||
|
||||
# Continuous Integration
|
||||
.drone.yml @grafana/grafana-release-eng
|
||||
.drone.star @grafana/grafana-release-eng
|
||||
/scripts/drone/ @grafana/grafana-release-eng
|
||||
|
||||
# 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
|
||||
|
||||
# Database migrations
|
||||
/pkg/services/sqlstore/migrations @grafana/backend-platform @grafana/hosted-grafana-team
|
||||
*_mig.go @grafana/backend-platform @grafana/hosted-grafana-team
|
||||
|
||||
# Grafana live
|
||||
/pkg/services/live/ @grafana/grafana-edge-squad
|
||||
|
||||
# Unified Alerting
|
||||
/pkg/services/ngalert @grafana/alerting-squad
|
||||
/pkg/services/sqlstore/migrations/ualert @grafana/alerting-squad
|
||||
|
||||
# Library Services
|
||||
/pkg/services/libraryelements @grafana/user-essentials
|
||||
/pkg/services/librarypanels @grafana/user-essentials
|
||||
|
||||
# Plugins
|
||||
/pkg/api/pluginproxy @grafana/plugins-platform-backend
|
||||
/pkg/plugins @grafana/plugins-platform-backend
|
||||
/pkg/services/datasourceproxy @grafana/plugins-platform-backend
|
||||
/pkg/services/datasources @grafana/plugins-platform-backend
|
||||
|
||||
# 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/user-essentials
|
||||
/packages @grafana/user-essentials @grafana/plugins-platform-frontend @grafana/grafana-bi-squad
|
||||
/packages/grafana-e2e-selectors @grafana/user-essentials
|
||||
/packages/grafana-e2e @grafana/user-essentials
|
||||
/packages/grafana-toolkit @grafana/plugins-platform-frontend
|
||||
/packages/grafana-ui/.storybook @grafana/plugins-platform-frontend
|
||||
/packages/grafana-ui/src/components/DateTimePickers @grafana/grafana-bi-squad
|
||||
/packages/grafana-ui/src/components/GraphNG @grafana/grafana-bi-squad
|
||||
/packages/grafana-ui/src/components/Table @grafana/grafana-bi-squad
|
||||
/packages/grafana-ui/src/components/TimeSeries @grafana/grafana-bi-squad
|
||||
/packages/grafana-ui/src/components/uPlot @grafana/grafana-bi-squad
|
||||
/packages/grafana-ui/src/utils/storybook @grafana/plugins-platform-frontend
|
||||
/packages/jaeger-ui-components/ @grafana/observability-squad
|
||||
/plugins-bundled @grafana/plugins-platform-frontend
|
||||
/public @grafana/user-essentials
|
||||
/public/app/core/components/TimePicker @grafana/grafana-bi-squad
|
||||
/public/app/features/canvas/ @grafana/grafana-edge-squad
|
||||
/public/app/features/dimensions/ @grafana/grafana-edge-squad
|
||||
/public/app/features/live/ @grafana/grafana-edge-squad
|
||||
/public/app/features/explore/ @grafana/observability-squad
|
||||
/public/app/features/plugins @grafana/plugins-platform-frontend
|
||||
/public/app/plugins/panel/alertlist @grafana/alerting-squad
|
||||
/public/app/plugins/panel/barchart @grafana/grafana-bi-squad
|
||||
/public/app/plugins/panel/heatmap @grafana/grafana-bi-squad
|
||||
/public/app/plugins/panel/histogram @grafana/grafana-bi-squad
|
||||
/public/app/plugins/panel/nodeGraph @grafana/observability-squad
|
||||
/public/app/plugins/panel/piechart @grafana/grafana-bi-squad
|
||||
/public/app/plugins/panel/state-timeline @grafana/grafana-bi-squad
|
||||
/public/app/plugins/panel/status-history @grafana/grafana-bi-squad
|
||||
/public/app/plugins/panel/table @grafana/grafana-bi-squad
|
||||
/public/app/plugins/panel/timeseries @grafana/grafana-bi-squad
|
||||
/public/app/plugins/panel/geomap @grafana/grafana-edge-squad
|
||||
/public/app/plugins/panel/canvas @grafana/grafana-edge-squad
|
||||
/public/app/plugins/panel/candlestick @grafana/grafana-edge-squad
|
||||
/public/app/plugins/panel/icon @grafana/grafana-edge-squad
|
||||
/scripts/build/release-packages.sh @grafana/plugins-platform-frontend
|
||||
/scripts/circle-release-next-packages.sh @grafana/plugins-platform-frontend
|
||||
/scripts/ci-frontend-metrics.sh @grafana/user-essentials @grafana/plugins-platform-frontend @grafana/grafana-bi-squad
|
||||
/scripts/ci-reference-docs-build.sh @grafana/plugins-platform-frontend
|
||||
/scripts/ci-reference-docs-lint.sh @grafana/plugins-platform-frontend
|
||||
/scripts/grunt @grafana/frontend-ops
|
||||
/scripts/webpack @grafana/frontend-ops
|
||||
/scripts/generate-a11y-report.sh @grafana/user-essentials
|
||||
package.json @grafana/frontend-ops
|
||||
tsconfig.json @grafana/frontend-ops
|
||||
lerna.json @grafana/frontend-ops
|
||||
.babelrc @grafana/frontend-ops
|
||||
.prettierrc.js @grafana/frontend-ops
|
||||
.eslintrc @grafana/frontend-ops
|
||||
.pa11yci.conf.js @grafana/user-essentials
|
||||
.pa11yci-pr.conf.js @grafana/user-essentials
|
||||
/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/plugins-platform-frontend
|
||||
*.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/cloudwatch @grafana/backend-platform @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/grafana-azure-monitor-datasource @grafana/backend-platform
|
||||
/public/app/plugins/datasource/graphite @grafana/observability-squad
|
||||
/public/app/plugins/datasource/influxdb @grafana/observability-squad
|
||||
/public/app/plugins/datasource/jaeger @grafana/observability-squad
|
||||
@@ -137,10 +56,5 @@ lerna.json @grafana/frontend-ops
|
||||
/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/cloud-monitoring @grafana/backend-platform
|
||||
/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
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/1-bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/1-bug_report.md
vendored
@@ -5,7 +5,7 @@ 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. Therefore take a couple of extra minutes to make sure you have provided all info needed.
|
||||
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.
|
||||
|
||||
|
||||
11
.github/ISSUE_TEMPLATE/2-feature_request.md
vendored
Normal file
11
.github/ISSUE_TEMPLATE/2-feature_request.md
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
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**:
|
||||
39
.github/ISSUE_TEMPLATE/3-grafana_ui_component.md
vendored
39
.github/ISSUE_TEMPLATE/3-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).
|
||||
39
.github/ISSUE_TEMPLATE/4-grafana_ui_component.md
vendored
Normal file
39
.github/ISSUE_TEMPLATE/4-grafana_ui_component.md
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
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/master/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/master/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).
|
||||
3
.github/ISSUE_TEMPLATE/config.yml
vendored
3
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,8 +1,5 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Feature Request
|
||||
url: https://github.com/grafana/grafana/discussions/new
|
||||
about: Discuss ideas for new features of changes
|
||||
- name: Questions & Help
|
||||
url: https://community.grafana.com
|
||||
about: Please ask and answer questions here.
|
||||
|
||||
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -2,7 +2,7 @@
|
||||
|
||||
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
|
||||
1. If this is your first time, please read our contribution guide at https://github.com/grafana/grafana/blob/master/CONTRIBUTING.md
|
||||
|
||||
2. Ensure you include and run the appropriate tests as part of your Pull Request.
|
||||
|
||||
@@ -10,7 +10,7 @@ Thank you for sending a pull request! Here are some tips:
|
||||
|
||||
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.
|
||||
5. If you can not merge your Pull Request due to a merge conflict, Rebase it. This gets it in sync with the master 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.
|
||||
|
||||
|
||||
7
.github/actions/gha-publish-to-git/Dockerfile
vendored
Normal file
7
.github/actions/gha-publish-to-git/Dockerfile
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
FROM alpine
|
||||
RUN apk update
|
||||
RUN apk add rsync git bash
|
||||
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
|
||||
21
.github/actions/gha-publish-to-git/LICENSE
vendored
Normal file
21
.github/actions/gha-publish-to-git/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Sean Middleditch
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
60
.github/actions/gha-publish-to-git/README.md
vendored
Normal file
60
.github/actions/gha-publish-to-git/README.md
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
publish-to-git
|
||||
==============
|
||||
|
||||
[GitHub Action](https://github.com/features/actions) for publishing a directory
|
||||
and its contents to another git repository.
|
||||
|
||||
This can be especially useful for publishing static website, such as with
|
||||
[GitHub Pages](https://pages.github.com/), from built files in other job
|
||||
steps, such as [Doxygen](http://www.doxygen.nl/) generated HTML files.
|
||||
|
||||
> **Note:** GitHub currently requires the use of a Personal Access Token for
|
||||
pushing to other repositories. Pushing to the current repository should work
|
||||
with the always-available GitHub Token (available via
|
||||
`{{ secrets.GITHUB_TOKEN }}`. If pushing to another repository, a Personal
|
||||
Access Token will need to be [created](https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line) and assigned to the
|
||||
workflow [secrets](https://help.github.com/en/articles/virtual-environments-for-github-actions#creating-and-using-secrets-encrypted-variables).
|
||||
|
||||
Inputs
|
||||
------
|
||||
|
||||
- `repository`: Destination repository (default: current repository).
|
||||
- `branch`: Destination branch (required).
|
||||
- `host`: Destination git host (default: `github.com`).
|
||||
- `github_token`: GitHub Token (required; use `secrets.GITHUB_TOKEN`).
|
||||
- `github_pat`: Personal Access Token or other https credentials.
|
||||
- `source_folder`: Source folder in workspace to copy (default: workspace root).
|
||||
- `target_folder`: Target folder in destination branch to copy to (default: repository root).
|
||||
- `commit_author`: Override commit author (default: `{github.actor}@users.noreply.github.com`).
|
||||
- `commit_message`: Set commit message (default: `[workflow] Publish from [repository]:[branch]/[folder]`).
|
||||
- `dry_run`: Does not push if non-empty (default: empty).
|
||||
- `working_directory`: Location to checkout repository (default: random location in `${HOME}`)
|
||||
|
||||
Outputs
|
||||
-------
|
||||
|
||||
- `commit_hash`: SHA hash of the new commit.
|
||||
- `working_directory`: Working directory of git clone of repository.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
MIT License. See [LICENSE](LICENSE) for details.
|
||||
|
||||
Usage Example
|
||||
-------------
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
publish:
|
||||
- uses: actions/checkout@master
|
||||
- run: |
|
||||
sh scripts/build-doxygen-html.sh --out static/html
|
||||
- uses: seanmiddleditch/gha-publish-to-git@master
|
||||
with:
|
||||
branch: gh-pages
|
||||
github_token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
github_pat: '${{ secrets.GH_PAT }}'
|
||||
source_folder: static/html
|
||||
if: success() && github.event == 'push'
|
||||
```
|
||||
60
.github/actions/gha-publish-to-git/action.yml
vendored
Normal file
60
.github/actions/gha-publish-to-git/action.yml
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
name: publish-to-git
|
||||
description: 'Publish files to a git repository'
|
||||
branding:
|
||||
icon: 'git-commit'
|
||||
color: 'blue'
|
||||
inputs:
|
||||
repository:
|
||||
description: 'Destination repository (default: current repository)'
|
||||
default: ''
|
||||
branch:
|
||||
description: 'Destination branch'
|
||||
required: true
|
||||
host:
|
||||
description: 'Destination git host'
|
||||
default: 'github.com'
|
||||
github_token:
|
||||
description: 'GitHub Token (use `secrets.GITHUB_TOKEN`)'
|
||||
required: true
|
||||
github_pat:
|
||||
description: 'Personal Access Token or other https credentials'
|
||||
default: ''
|
||||
source_folder:
|
||||
description: 'Source folder in workspace to copy (default: workspace root)'
|
||||
defaault: ''
|
||||
target_folder:
|
||||
description: 'Target folder in destination branch to copy to (default: repository root)'
|
||||
default: ''
|
||||
commit_author:
|
||||
description: 'User Name <email@address> (default: [github.actor]@users.noreply.github.com)'
|
||||
default: ''
|
||||
commit_message:
|
||||
description: 'Commit message (default: [workflow] Publish from [repository]:[branch]/[folder])'
|
||||
default: ''
|
||||
dry_run:
|
||||
description: 'Do not push to repository (set to non-empty string to make dry-run)'
|
||||
default: ''
|
||||
working_directory:
|
||||
description: 'Working directory for clone (default: random location in `${HOME}`)'
|
||||
default: ''
|
||||
outputs:
|
||||
commit_hash:
|
||||
description: 'Hash of the new commit'
|
||||
working_directory:
|
||||
description: 'Working directory of temporary repository'
|
||||
runs:
|
||||
using: 'docker'
|
||||
image: 'Dockerfile'
|
||||
args:
|
||||
- ${{ inputs.repository }}
|
||||
- ${{ inputs.branch }}
|
||||
- ${{ inputs.host }}
|
||||
- ${{ inputs.github_token }}
|
||||
- ${{ inputs.github_pat }}
|
||||
- ${{ inputs.source_folder }}
|
||||
- ${{ inputs.target_folder }}
|
||||
- ${{ inputs.commit_author }}
|
||||
- ${{ inputs.commit_message }}
|
||||
- ${{ inputs.dry_run }}
|
||||
- ${{ inputs.working_directory }}
|
||||
99
.github/actions/gha-publish-to-git/entrypoint.sh
vendored
Normal file
99
.github/actions/gha-publish-to-git/entrypoint.sh
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
#/bin/bash
|
||||
|
||||
# Name the Docker inputs.
|
||||
#
|
||||
INPUT_REPOSITORY="$1"
|
||||
INPUT_BRANCH="$2"
|
||||
INPUT_HOST="$3"
|
||||
INPUT_GITHUB_TOKEN="$4"
|
||||
INPUT_GITHUB_PAT="$5"
|
||||
INPUT_SOURCE_FOLDER="$6"
|
||||
INPUT_TARGET_FOLDER="$7"
|
||||
INPUT_COMMIT_AUTHOR="$8"
|
||||
INPUT_COMMIT_MESSAGE="$9"
|
||||
INPUT_DRYRUN="${10}"
|
||||
INPUT_WORKDIR="${11}"
|
||||
|
||||
# Check for required inputs.
|
||||
#
|
||||
[ -z "$INPUT_BRANCH" ] && echo >&2 "::error::'branch' is required" && exit 1
|
||||
[ -z "$INPUT_GITHUB_TOKEN" -a -z "$INPUT_GITHUB_PAT" ] && echo >&2 "::error::'github_token' or 'github_pat' is required" && exit 1
|
||||
|
||||
# Set state from inputs or defaults.
|
||||
#
|
||||
REPOSITORY="${INPUT_REPOSITORY:-${GITHUB_REPOSITORY}}"
|
||||
BRANCH="${INPUT_BRANCH}"
|
||||
HOST="${INPUT_GIT_HOST:-github.com}"
|
||||
TOKEN="${INPUT_GITHUB_PAT:-${INPUT_GITHUB_TOKEN}}"
|
||||
REMOTE="${INPUT_REMOTE:-https://${TOKEN}@${HOST}/${REPOSITORY}.git}"
|
||||
|
||||
SOURCE_FOLDER="${INPUT_SOURCE_FOLDER:-.}"
|
||||
TARGET_FOLDER="${INPUT_TARGET_FOLDER}"
|
||||
|
||||
REF="${GITHUB_BASE_REF:-${GITHUB_REF}}"
|
||||
REF_BRANCH=$(echo "${REF}" | rev | cut -d/ -f1 | rev)
|
||||
[ -z "$REF_BRANCH" ] && echo 2>&1 "No ref branch" && exit 1
|
||||
|
||||
COMMIT_AUTHOR="${INPUT_AUTHOR:-${GITHUB_ACTOR} <${GITHUB_ACTOR}@users.noreply.github.com>}"
|
||||
COMMIT_MESSAGE="${INPUT_COMMIT_MESSAGE:-[${GITHUB_WORKFLOW}] Publish from ${GITHUB_REPOSITORY}:${REF_BRANCH}/${SOURCE_FOLDER}}"
|
||||
|
||||
# Calculate the real source path.
|
||||
#
|
||||
SOURCE_PATH="$(realpath "${SOURCE_FOLDER}")"
|
||||
[ -z "${SOURCE_PATH}" ] && exit 1
|
||||
echo "::debug::SOURCE_PATH=${SOURCE_PATH}"
|
||||
|
||||
# Let's start doing stuff.
|
||||
echo "Publishing ${SOURCE_FOLDER} to ${REMOTE}:${BRANCH}/${TARGET_FOLDER}"
|
||||
|
||||
# Create a working directory; the workspace may be filled with other important
|
||||
# files.
|
||||
#
|
||||
WORK_DIR="${INPUT_WORKDIR:-$(mktemp -d "${HOME}/gitrepo.XXXXXX")}"
|
||||
[ -z "${WORK_DIR}" ] && echo >&2 "::error::Failed to create temporary working directory" && exit 1
|
||||
cd "${WORK_DIR}"
|
||||
|
||||
# Initialize git repo and configure for remote access.
|
||||
#
|
||||
echo "Initializing repository with remote ${REMOTE}"
|
||||
git init || exit 1
|
||||
git config --local user.email "${GITHUB_ACTOR}@users.noreply.github.com" || exit 1
|
||||
git config --local user.name "${GITHUB_ACTOR}" || exit 1
|
||||
git remote add origin "${REMOTE}" || exit 1
|
||||
git remote -v
|
||||
|
||||
# Fetch initial (current contents).
|
||||
#
|
||||
echo "Fetching ${REMOTE}:${BRANCH}"
|
||||
git fetch --depth 1 origin "${BRANCH}" || exit 1
|
||||
git checkout -b "${BRANCH}" || exit 1
|
||||
git pull origin "${BRANCH}" || exit 1
|
||||
|
||||
# Create the target directory (if necessary) and copy files from source.
|
||||
#
|
||||
TARGET_PATH="${WORK_DIR}/${TARGET_FOLDER}"
|
||||
echo "Populating ${TARGET_PATH}"
|
||||
mkdir -p "${TARGET_PATH}" || exit 1
|
||||
rsync -a --quiet --delete "${SOURCE_PATH}/" "${TARGET_PATH}" || exit 1
|
||||
|
||||
# Create commit with changes.
|
||||
#
|
||||
echo "Creating commit"
|
||||
git add "${TARGET_PATH}" || exit 1
|
||||
git commit -m "${COMMIT_MESSAGE}" --author "${COMMIT_AUTHOR}" || exit 1
|
||||
COMMIT_HASH="$(git rev-parse HEAD)"
|
||||
echo "Created commit ${COMMIT_HASH}"
|
||||
|
||||
# Publish output variables.
|
||||
#
|
||||
echo "::set-output name=commit_hash::${COMMIT_HASH}"
|
||||
echo "::set-output name=working_directory::${WORK_DIR}"
|
||||
|
||||
# Push if not a dry-run.
|
||||
#
|
||||
if [ -z "${INPUT_DRYRUN}" ] ; then
|
||||
echo "Pushing to ${REMOTE}:${BRANCH}"
|
||||
git push origin "${BRANCH}" || exit 1
|
||||
else
|
||||
echo "[DRY-RUN] Not pushing to ${REMOTE}:${BRANCH}"
|
||||
fi
|
||||
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)
|
||||
38
.github/commands.json
vendored
38
.github/commands.json
vendored
@@ -1,11 +1,9 @@
|
||||
[
|
||||
{
|
||||
"type": "label",
|
||||
"name": "bot/question",
|
||||
"addLabel": "type/question",
|
||||
"removeLabel": "bot/question",
|
||||
"name": "type/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!"
|
||||
"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/master/CONTRIBUTING.md) guidelines.\n\nHappy graphing!"
|
||||
},
|
||||
{
|
||||
"type": "comment",
|
||||
@@ -16,38 +14,14 @@
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "bot/duplicate",
|
||||
"addLabel": "type/duplicate",
|
||||
"removeLabel": "bot/duplicate",
|
||||
"name": "type/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"
|
||||
"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/master/CONTRIBUTING.md) guidelines.\n\nHappy graphing!"
|
||||
},
|
||||
{
|
||||
"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",
|
||||
"name": "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!"
|
||||
"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/master/CONTRIBUTING.md) guidelines.\n\nHappy graphing!"
|
||||
}
|
||||
]
|
||||
|
||||
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"
|
||||
}
|
||||
]
|
||||
}
|
||||
189
.github/pr-commands.json
vendored
189
.github/pr-commands.json
vendored
@@ -1,189 +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",
|
||||
"Makefile",
|
||||
"Dockerfile",
|
||||
"Dockerfile.ubuntu"
|
||||
],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "type/build-packaging"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [
|
||||
"scripts/*.star",
|
||||
".drone.star",
|
||||
".drone.yml"
|
||||
],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "type/ci"
|
||||
},
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
40
.github/renovate.json5
vendored
40
.github/renovate.json5
vendored
@@ -1,40 +0,0 @@
|
||||
{
|
||||
"extends": [
|
||||
"config:base"
|
||||
],
|
||||
"enabledManagers": ["npm"],
|
||||
"ignoreDeps": [
|
||||
"@types/systemjs",
|
||||
"@types/d3-force", // we should bump this once we move to esm modules
|
||||
"@types/d3-interpolate", // we should bump this once we move to esm modules
|
||||
"@types/d3-scale-chromatic", // we should bump this once we move to esm modules
|
||||
"d3",
|
||||
"d3-force", // we should bump this once we move to esm modules
|
||||
"d3-interpolate", // we should bump this once we move to esm modules
|
||||
"d3-scale-chromatic", // we should bump this once we move to esm modules
|
||||
"eslint", // wait until `eslint-plugin-react-hooks>4.2.0` is released
|
||||
"globby", // we should bump this once we move to esm modules
|
||||
"slate",
|
||||
"slate-plain-serializer",
|
||||
"systemjs",
|
||||
"ts-loader", // we should remove ts-loader and use babel-loader instead
|
||||
"ora" // we should bump this once we move to esm modules
|
||||
],
|
||||
"ignorePaths": ["packages/grafana-toolkit/package.json", "emails/**", "plugins-bundled/**", "**/mocks/**"],
|
||||
"labels": ["area/frontend", "dependencies"],
|
||||
"minor": {
|
||||
"enabled": false
|
||||
},
|
||||
"patch": {
|
||||
"enabled": false
|
||||
},
|
||||
"pin": {
|
||||
"enabled": false
|
||||
},
|
||||
"prConcurrentLimit": 10,
|
||||
"reviewers": ["team:grafana/frontend-ops"],
|
||||
"separateMajorMinor": false,
|
||||
"vulnerabilityAlerts": {
|
||||
"addLabels": ["area/security"]
|
||||
}
|
||||
}
|
||||
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.0.2
|
||||
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.4.1
|
||||
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}}
|
||||
11
.github/workflows/codeql-analysis.yml
vendored
11
.github/workflows/codeql-analysis.yml
vendored
@@ -7,10 +7,10 @@ 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]
|
||||
branches: [master, 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]
|
||||
branches: [master]
|
||||
schedule:
|
||||
- cron: '0 4 * * 6'
|
||||
|
||||
@@ -36,13 +36,18 @@ jobs:
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
# If this run was triggered by a pull request event, then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
# 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.
|
||||
# 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
|
||||
|
||||
|
||||
2
.github/workflows/commands.yml
vendored
2
.github/workflows/commands.yml
vendored
@@ -22,4 +22,4 @@ jobs:
|
||||
with:
|
||||
metricsWriteAPIKey: ${{secrets.GRAFANA_MISC_STATS_API_KEY}}
|
||||
token: ${{secrets.GH_BOT_ACCESS_TOKEN}}
|
||||
configPath: commands
|
||||
config-path: 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}}
|
||||
3
.github/workflows/metrics-collector.yml
vendored
3
.github/workflows/metrics-collector.yml
vendored
@@ -8,7 +8,7 @@
|
||||
#
|
||||
# https://github.com/grafana/grafana-github-actions/blob/main/metrics-collector/index.ts
|
||||
#
|
||||
name: Github issue metrics collection
|
||||
name: Github issue metrics collection
|
||||
on:
|
||||
schedule:
|
||||
- cron: "*/10 * * * *"
|
||||
@@ -32,4 +32,3 @@ jobs:
|
||||
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
|
||||
25
.github/workflows/publish.yml
vendored
25
.github/workflows/publish.yml
vendored
@@ -3,7 +3,7 @@ name: publish_docs
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
paths:
|
||||
- 'docs/sources/**'
|
||||
- 'packages/grafana-*/**'
|
||||
@@ -15,25 +15,15 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- run: git clone --single-branch --no-tags --depth 1 -b master https://grafanabot:${{ secrets.GH_BOT_ACCESS_TOKEN }}@github.com/grafana/website-sync ./.github/actions/website-sync
|
||||
- name: generate-packages-docs
|
||||
uses: actions/setup-node@v2.4.1
|
||||
uses: actions/setup-node@v1
|
||||
id: generate-docs
|
||||
with:
|
||||
node-version: '14'
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn config get cacheFolder)"
|
||||
- uses: actions/cache@v2.1.6
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
yarn-
|
||||
- run: yarn install --immutable
|
||||
node-version: '12'
|
||||
- run: yarn install --pure-lockfile --no-progress
|
||||
- run: ./scripts/ci-reference-docs-build.sh
|
||||
- name: publish-to-git
|
||||
uses: ./.github/actions/website-sync
|
||||
uses: ./.github/actions/gha-publish-to-git
|
||||
id: publish
|
||||
with:
|
||||
repository: grafana/website
|
||||
@@ -41,9 +31,8 @@ jobs:
|
||||
host: github.com
|
||||
github_pat: '${{ secrets.GH_BOT_ACCESS_TOKEN }}'
|
||||
source_folder: docs/sources
|
||||
target_folder: content/docs/grafana/next
|
||||
allow_no_changes: 'true'
|
||||
target_folder: content/docs/grafana/latest
|
||||
- shell: bash
|
||||
run: |
|
||||
test -n "${{ steps.publish.outputs.commit_hash }}"
|
||||
test -n "${{ steps.publish.outputs.working_directory }}"
|
||||
test -n "${{ steps.publish.outputs.working_directory }}"
|
||||
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}}
|
||||
37
.gitignore
vendored
37
.gitignore
vendored
@@ -7,35 +7,19 @@ awsconfig
|
||||
/.awcache
|
||||
/dist
|
||||
/public/build
|
||||
public/dist/tsconfig.tsbuildinfo
|
||||
/public/views/index.html
|
||||
/public/views/error.html
|
||||
/emails/dist
|
||||
/reports
|
||||
/e2e/tmp
|
||||
.yarnrc
|
||||
.yarn/
|
||||
vendor/
|
||||
/docs/menu.yaml
|
||||
/requests
|
||||
|
||||
# Yarn
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/releases
|
||||
!.yarn/plugins
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
# we temporarily commit this file because yarn downloading it
|
||||
# somehow produces different checksum values
|
||||
!.yarn/cache/pa11y-ci-https-1e9675e9e1-668c9119bd.zip
|
||||
.pnp.*
|
||||
|
||||
# Enterprise emails
|
||||
/emails/templates/enterprise_*
|
||||
/public/emails/enterprise_*
|
||||
|
||||
# Enterprise reporting fonts
|
||||
/public/fonts/dejavu
|
||||
|
||||
# Enterprise devenv
|
||||
/devenv/docker/blocks/grafana-enterprise
|
||||
|
||||
@@ -61,10 +45,8 @@ public/css/*.min.css
|
||||
*.tmp
|
||||
.DS_Store
|
||||
.vscode/
|
||||
!.vscode/launch.json
|
||||
.vs/
|
||||
.eslintcache
|
||||
.stylelintcache
|
||||
|
||||
/data/*
|
||||
/bin/*
|
||||
@@ -87,8 +69,6 @@ profile.cov
|
||||
/pkg/cmd/grafana-server/grafana-server
|
||||
/pkg/cmd/grafana-server/debug
|
||||
/pkg/extensions/*
|
||||
/pkg/server/wireexts_enterprise.go
|
||||
/pkg/cmd/grafana-cli/runner/wireexts_enterprise.go
|
||||
!/pkg/extensions/main.go
|
||||
/public/app/extensions
|
||||
debug.test
|
||||
@@ -96,7 +76,6 @@ debug.test
|
||||
/packaging/**/*.rpm
|
||||
/packaging/**/*.deb
|
||||
/packaging/**/*.tar.gz
|
||||
/packaging/**/*.tar.gz.sha256
|
||||
|
||||
# Ignore OSX indexing
|
||||
.DS_Store
|
||||
@@ -137,17 +116,5 @@ compilation-stats.json
|
||||
!/e2e/**/screenshots/expected/*
|
||||
/e2e/**/videos/*
|
||||
|
||||
# a11y tests
|
||||
/pa11y-ci-results.json
|
||||
/pa11y-ci-report
|
||||
|
||||
# report dumping the whole system env
|
||||
/report.*.json
|
||||
|
||||
# auto generated frontend docs
|
||||
/docs/sources/packages_api
|
||||
|
||||
# auto generated Go files
|
||||
*_gen.go
|
||||
|
||||
deployment_tools_config.json
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
yarn run precommit
|
||||
@@ -1,121 +0,0 @@
|
||||
var config = {
|
||||
defaults: {
|
||||
concurrency: 1,
|
||||
runners: ['axe'],
|
||||
useIncognitoBrowserContext: false,
|
||||
chromeLaunchConfig: {
|
||||
args: ['--no-sandbox'],
|
||||
},
|
||||
hideElements: '#updateVersion',
|
||||
},
|
||||
|
||||
urls: [
|
||||
{
|
||||
url: '${HOST}/login',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
threshold: 12,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/login',
|
||||
wait: 500,
|
||||
actions: [
|
||||
"wait for element input[name='user'] to be added",
|
||||
"set field input[name='user'] to admin",
|
||||
"set field input[name='password'] to admin",
|
||||
"click element button[aria-label='Login button']",
|
||||
"wait for element [aria-label='Skip change password button'] to be visible",
|
||||
],
|
||||
threshold: 13,
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/?orgId=1',
|
||||
wait: 500,
|
||||
threshold: 0,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/d/O6f11TZWk/panel-tests-bar-gauge',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
threshold: 0,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/d/O6f11TZWk/panel-tests-bar-gauge?orgId=1&editview=settings',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
threshold: 0,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/?orgId=1&search=open',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
threshold: 0,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/alerting/list',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
// the unified alerting promotion alert's content contrast is too low
|
||||
// see https://github.com/grafana/grafana/pull/41829
|
||||
threshold: 5,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/datasources',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
threshold: 0,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/org/users',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
threshold: 0,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/org/teams',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
threshold: 0,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/plugins',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
threshold: 0,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/org',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
threshold: 0,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/org/apikeys',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
threshold: 0,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/dashboards',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
threshold: 0,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
function myPa11yCiConfiguration(urls, defaults) {
|
||||
const HOST_SERVER = process.env.HOST || 'localhost';
|
||||
const PORT_SERVER = process.env.PORT || '3001';
|
||||
for (var idx = 0; idx < urls.length; idx++) {
|
||||
urls[idx] = { ...urls[idx], url: urls[idx].url.replace('${HOST}', `${HOST_SERVER}:${PORT_SERVER}`) };
|
||||
}
|
||||
|
||||
return {
|
||||
defaults: defaults,
|
||||
urls: urls,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = myPa11yCiConfiguration(config.urls, config.defaults);
|
||||
104
.pa11yci.conf.js
104
.pa11yci.conf.js
@@ -1,104 +0,0 @@
|
||||
var config = {
|
||||
defaults: {
|
||||
concurrency: 1,
|
||||
runners: ['axe'],
|
||||
useIncognitoBrowserContext: false,
|
||||
chromeLaunchConfig: {
|
||||
args: ['--no-sandbox'],
|
||||
},
|
||||
hideElements: '#updateVersion',
|
||||
},
|
||||
|
||||
urls: [
|
||||
{
|
||||
url: '${HOST}/login',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/login', //skip password and login
|
||||
actions: [
|
||||
"wait for element input[name='user'] to be added",
|
||||
"set field input[name='user'] to admin",
|
||||
"set field input[name='password'] to admin",
|
||||
"click element button[aria-label='Login button']",
|
||||
"wait for element [aria-label='Skip change password button'] to be visible",
|
||||
],
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/?orgId=1',
|
||||
wait: 500,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/d/O6f11TZWk/panel-tests-bar-gauge',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/d/O6f11TZWk/panel-tests-bar-gauge?orgId=1&editview=settings',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/?orgId=1&search=open',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/alerting/list',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/datasources',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/org/users',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/org/teams',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/plugins',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/org',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/org/apikeys',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/dashboards',
|
||||
wait: 500,
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
function myPa11yCiConfiguration(urls, defaults) {
|
||||
const HOST_SERVER = process.env.HOST || 'localhost';
|
||||
const PORT_SERVER = process.env.PORT || '3001';
|
||||
for (var idx = 0; idx < urls.length; idx++) {
|
||||
urls[idx] = { ...urls[idx], url: urls[idx].url.replace('${HOST}', `${HOST_SERVER}:${PORT_SERVER}`) };
|
||||
}
|
||||
return {
|
||||
defaults: defaults,
|
||||
urls: urls,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = myPa11yCiConfiguration(config.urls, config.defaults);
|
||||
@@ -5,9 +5,5 @@ pkg/
|
||||
node_modules
|
||||
public/vendor/
|
||||
vendor/
|
||||
/data/
|
||||
data/
|
||||
e2e/tmp
|
||||
public/build/
|
||||
public/sass/*.generated.scss
|
||||
devenv/
|
||||
public/lib/monaco
|
||||
|
||||
23
.vscode/launch.json
vendored
23
.vscode/launch.json
vendored
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Run Server",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "${workspaceFolder}/pkg/cmd/grafana-server/",
|
||||
"env": {},
|
||||
"args": ["--homepath", "${workspaceFolder}", "--packaging", "dev"]
|
||||
},
|
||||
{
|
||||
"name": "Debug Jest test",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"runtimeArgs": ["--inspect-brk", "${workspaceRoot}/node_modules/.bin/jest", "--runInBand", "${file}"],
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"port": 9229
|
||||
}
|
||||
]
|
||||
}
|
||||
546
.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
vendored
546
.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
vendored
File diff suppressed because one or more lines are too long
33
.yarn/plugins/@yarnpkg/plugin-outdated.cjs
vendored
33
.yarn/plugins/@yarnpkg/plugin-outdated.cjs
vendored
File diff suppressed because one or more lines are too long
9
.yarn/plugins/@yarnpkg/plugin-typescript.cjs
vendored
9
.yarn/plugins/@yarnpkg/plugin-typescript.cjs
vendored
File diff suppressed because one or more lines are too long
768
.yarn/releases/yarn-3.1.0.cjs
vendored
768
.yarn/releases/yarn-3.1.0.cjs
vendored
File diff suppressed because one or more lines are too long
20
.yarn/sdks/eslint/bin/eslint.js
vendored
20
.yarn/sdks/eslint/bin/eslint.js
vendored
@@ -1,20 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const {existsSync} = require(`fs`);
|
||||
const {createRequire, createRequireFromPath} = require(`module`);
|
||||
const {resolve} = require(`path`);
|
||||
|
||||
const relPnpApiPath = "../../../../.pnp.cjs";
|
||||
|
||||
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
|
||||
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
|
||||
|
||||
if (existsSync(absPnpApiPath)) {
|
||||
if (!process.versions.pnp) {
|
||||
// Setup the environment to be able to require eslint/bin/eslint.js
|
||||
require(absPnpApiPath).setup();
|
||||
}
|
||||
}
|
||||
|
||||
// Defer to the real eslint/bin/eslint.js your application uses
|
||||
module.exports = absRequire(`eslint/bin/eslint.js`);
|
||||
20
.yarn/sdks/eslint/lib/api.js
vendored
20
.yarn/sdks/eslint/lib/api.js
vendored
@@ -1,20 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const {existsSync} = require(`fs`);
|
||||
const {createRequire, createRequireFromPath} = require(`module`);
|
||||
const {resolve} = require(`path`);
|
||||
|
||||
const relPnpApiPath = "../../../../.pnp.cjs";
|
||||
|
||||
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
|
||||
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
|
||||
|
||||
if (existsSync(absPnpApiPath)) {
|
||||
if (!process.versions.pnp) {
|
||||
// Setup the environment to be able to require eslint/lib/api.js
|
||||
require(absPnpApiPath).setup();
|
||||
}
|
||||
}
|
||||
|
||||
// Defer to the real eslint/lib/api.js your application uses
|
||||
module.exports = absRequire(`eslint/lib/api.js`);
|
||||
6
.yarn/sdks/eslint/package.json
vendored
6
.yarn/sdks/eslint/package.json
vendored
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"name": "eslint",
|
||||
"version": "7.21.0-sdk",
|
||||
"main": "./lib/api.js",
|
||||
"type": "commonjs"
|
||||
}
|
||||
6
.yarn/sdks/integrations.yml
vendored
6
.yarn/sdks/integrations.yml
vendored
@@ -1,6 +0,0 @@
|
||||
# This file is automatically generated by @yarnpkg/sdks.
|
||||
# Manual changes might be lost!
|
||||
|
||||
integrations:
|
||||
- vim
|
||||
- vscode
|
||||
20
.yarn/sdks/prettier/index.js
vendored
20
.yarn/sdks/prettier/index.js
vendored
@@ -1,20 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const {existsSync} = require(`fs`);
|
||||
const {createRequire, createRequireFromPath} = require(`module`);
|
||||
const {resolve} = require(`path`);
|
||||
|
||||
const relPnpApiPath = "../../../.pnp.cjs";
|
||||
|
||||
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
|
||||
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
|
||||
|
||||
if (existsSync(absPnpApiPath)) {
|
||||
if (!process.versions.pnp) {
|
||||
// Setup the environment to be able to require prettier/index.js
|
||||
require(absPnpApiPath).setup();
|
||||
}
|
||||
}
|
||||
|
||||
// Defer to the real prettier/index.js your application uses
|
||||
module.exports = absRequire(`prettier/index.js`);
|
||||
6
.yarn/sdks/prettier/package.json
vendored
6
.yarn/sdks/prettier/package.json
vendored
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"name": "prettier",
|
||||
"version": "2.2.1-sdk",
|
||||
"main": "./index.js",
|
||||
"type": "commonjs"
|
||||
}
|
||||
20
.yarn/sdks/stylelint/bin/stylelint.js
vendored
20
.yarn/sdks/stylelint/bin/stylelint.js
vendored
@@ -1,20 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const {existsSync} = require(`fs`);
|
||||
const {createRequire, createRequireFromPath} = require(`module`);
|
||||
const {resolve} = require(`path`);
|
||||
|
||||
const relPnpApiPath = "../../../../.pnp.cjs";
|
||||
|
||||
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
|
||||
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
|
||||
|
||||
if (existsSync(absPnpApiPath)) {
|
||||
if (!process.versions.pnp) {
|
||||
// Setup the environment to be able to require stylelint/bin/stylelint.js
|
||||
require(absPnpApiPath).setup();
|
||||
}
|
||||
}
|
||||
|
||||
// Defer to the real stylelint/bin/stylelint.js your application uses
|
||||
module.exports = absRequire(`stylelint/bin/stylelint.js`);
|
||||
20
.yarn/sdks/stylelint/lib/index.js
vendored
20
.yarn/sdks/stylelint/lib/index.js
vendored
@@ -1,20 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const {existsSync} = require(`fs`);
|
||||
const {createRequire, createRequireFromPath} = require(`module`);
|
||||
const {resolve} = require(`path`);
|
||||
|
||||
const relPnpApiPath = "../../../../.pnp.cjs";
|
||||
|
||||
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
|
||||
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
|
||||
|
||||
if (existsSync(absPnpApiPath)) {
|
||||
if (!process.versions.pnp) {
|
||||
// Setup the environment to be able to require stylelint/lib/index.js
|
||||
require(absPnpApiPath).setup();
|
||||
}
|
||||
}
|
||||
|
||||
// Defer to the real stylelint/lib/index.js your application uses
|
||||
module.exports = absRequire(`stylelint/lib/index.js`);
|
||||
6
.yarn/sdks/stylelint/package.json
vendored
6
.yarn/sdks/stylelint/package.json
vendored
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"name": "stylelint",
|
||||
"version": "13.13.1-sdk",
|
||||
"main": "lib/index.js",
|
||||
"type": "commonjs"
|
||||
}
|
||||
20
.yarn/sdks/typescript/bin/tsc
vendored
20
.yarn/sdks/typescript/bin/tsc
vendored
@@ -1,20 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const {existsSync} = require(`fs`);
|
||||
const {createRequire, createRequireFromPath} = require(`module`);
|
||||
const {resolve} = require(`path`);
|
||||
|
||||
const relPnpApiPath = "../../../../.pnp.cjs";
|
||||
|
||||
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
|
||||
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
|
||||
|
||||
if (existsSync(absPnpApiPath)) {
|
||||
if (!process.versions.pnp) {
|
||||
// Setup the environment to be able to require typescript/bin/tsc
|
||||
require(absPnpApiPath).setup();
|
||||
}
|
||||
}
|
||||
|
||||
// Defer to the real typescript/bin/tsc your application uses
|
||||
module.exports = absRequire(`typescript/bin/tsc`);
|
||||
20
.yarn/sdks/typescript/bin/tsserver
vendored
20
.yarn/sdks/typescript/bin/tsserver
vendored
@@ -1,20 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const {existsSync} = require(`fs`);
|
||||
const {createRequire, createRequireFromPath} = require(`module`);
|
||||
const {resolve} = require(`path`);
|
||||
|
||||
const relPnpApiPath = "../../../../.pnp.cjs";
|
||||
|
||||
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
|
||||
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
|
||||
|
||||
if (existsSync(absPnpApiPath)) {
|
||||
if (!process.versions.pnp) {
|
||||
// Setup the environment to be able to require typescript/bin/tsserver
|
||||
require(absPnpApiPath).setup();
|
||||
}
|
||||
}
|
||||
|
||||
// Defer to the real typescript/bin/tsserver your application uses
|
||||
module.exports = absRequire(`typescript/bin/tsserver`);
|
||||
20
.yarn/sdks/typescript/lib/tsc.js
vendored
20
.yarn/sdks/typescript/lib/tsc.js
vendored
@@ -1,20 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const {existsSync} = require(`fs`);
|
||||
const {createRequire, createRequireFromPath} = require(`module`);
|
||||
const {resolve} = require(`path`);
|
||||
|
||||
const relPnpApiPath = "../../../../.pnp.cjs";
|
||||
|
||||
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
|
||||
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
|
||||
|
||||
if (existsSync(absPnpApiPath)) {
|
||||
if (!process.versions.pnp) {
|
||||
// Setup the environment to be able to require typescript/lib/tsc.js
|
||||
require(absPnpApiPath).setup();
|
||||
}
|
||||
}
|
||||
|
||||
// Defer to the real typescript/lib/tsc.js your application uses
|
||||
module.exports = absRequire(`typescript/lib/tsc.js`);
|
||||
184
.yarn/sdks/typescript/lib/tsserver.js
vendored
184
.yarn/sdks/typescript/lib/tsserver.js
vendored
@@ -1,184 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const {existsSync} = require(`fs`);
|
||||
const {createRequire, createRequireFromPath} = require(`module`);
|
||||
const {resolve} = require(`path`);
|
||||
|
||||
const relPnpApiPath = "../../../../.pnp.cjs";
|
||||
|
||||
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
|
||||
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
|
||||
|
||||
const moduleWrapper = tsserver => {
|
||||
if (!process.versions.pnp) {
|
||||
return tsserver;
|
||||
}
|
||||
|
||||
const {isAbsolute} = require(`path`);
|
||||
const pnpApi = require(`pnpapi`);
|
||||
|
||||
const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//);
|
||||
const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`);
|
||||
|
||||
const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => {
|
||||
return `${locator.name}@${locator.reference}`;
|
||||
}));
|
||||
|
||||
// VSCode sends the zip paths to TS using the "zip://" prefix, that TS
|
||||
// doesn't understand. This layer makes sure to remove the protocol
|
||||
// before forwarding it to TS, and to add it back on all returned paths.
|
||||
|
||||
function toEditorPath(str) {
|
||||
// We add the `zip:` prefix to both `.zip/` paths and virtual paths
|
||||
if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) {
|
||||
// We also take the opportunity to turn virtual paths into physical ones;
|
||||
// this makes it much easier to work with workspaces that list peer
|
||||
// dependencies, since otherwise Ctrl+Click would bring us to the virtual
|
||||
// file instances instead of the real ones.
|
||||
//
|
||||
// We only do this to modules owned by the the dependency tree roots.
|
||||
// This avoids breaking the resolution when jumping inside a vendor
|
||||
// with peer dep (otherwise jumping into react-dom would show resolution
|
||||
// errors on react).
|
||||
//
|
||||
const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str;
|
||||
if (resolved) {
|
||||
const locator = pnpApi.findPackageLocator(resolved);
|
||||
if (locator && dependencyTreeRoots.has(`${locator.name}@${locator.reference}`)) {
|
||||
str = resolved;
|
||||
}
|
||||
}
|
||||
|
||||
str = normalize(str);
|
||||
|
||||
if (str.match(/\.zip\//)) {
|
||||
switch (hostInfo) {
|
||||
// Absolute VSCode `Uri.fsPath`s need to start with a slash.
|
||||
// VSCode only adds it automatically for supported schemes,
|
||||
// so we have to do it manually for the `zip` scheme.
|
||||
// The path needs to start with a caret otherwise VSCode doesn't handle the protocol
|
||||
//
|
||||
// Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910
|
||||
//
|
||||
// Update Oct 8 2021: VSCode changed their format in 1.61.
|
||||
// Before | ^zip:/c:/foo/bar.zip/package.json
|
||||
// After | ^/zip//c:/foo/bar.zip/package.json
|
||||
//
|
||||
case `vscode <1.61`: {
|
||||
str = `^zip:${str}`;
|
||||
} break;
|
||||
|
||||
case `vscode`: {
|
||||
str = `^/zip/${str}`;
|
||||
} break;
|
||||
|
||||
// To make "go to definition" work,
|
||||
// We have to resolve the actual file system path from virtual path
|
||||
// and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip)
|
||||
case `coc-nvim`: {
|
||||
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
|
||||
str = resolve(`zipfile:${str}`);
|
||||
} break;
|
||||
|
||||
// Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server)
|
||||
// We have to resolve the actual file system path from virtual path,
|
||||
// everything else is up to neovim
|
||||
case `neovim`: {
|
||||
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
|
||||
str = `zipfile:${str}`;
|
||||
} break;
|
||||
|
||||
default: {
|
||||
str = `zip:${str}`;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
function fromEditorPath(str) {
|
||||
switch (hostInfo) {
|
||||
case `coc-nvim`:
|
||||
case `neovim`: {
|
||||
str = str.replace(/\.zip::/, `.zip/`);
|
||||
// The path for coc-nvim is in format of /<pwd>/zipfile:/<pwd>/.yarn/...
|
||||
// So in order to convert it back, we use .* to match all the thing
|
||||
// before `zipfile:`
|
||||
return process.platform === `win32`
|
||||
? str.replace(/^.*zipfile:\//, ``)
|
||||
: str.replace(/^.*zipfile:/, ``);
|
||||
} break;
|
||||
|
||||
case `vscode`:
|
||||
default: {
|
||||
return process.platform === `win32`
|
||||
? str.replace(/^\^?(zip:|\/zip)\/+/, ``)
|
||||
: str.replace(/^\^?(zip:|\/zip)\/+/, `/`);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
// Force enable 'allowLocalPluginLoads'
|
||||
// TypeScript tries to resolve plugins using a path relative to itself
|
||||
// which doesn't work when using the global cache
|
||||
// https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238
|
||||
// VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but
|
||||
// TypeScript already does local loads and if this code is running the user trusts the workspace
|
||||
// https://github.com/microsoft/vscode/issues/45856
|
||||
const ConfiguredProject = tsserver.server.ConfiguredProject;
|
||||
const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype;
|
||||
ConfiguredProject.prototype.enablePluginsWithOptions = function() {
|
||||
this.projectService.allowLocalPluginLoads = true;
|
||||
return originalEnablePluginsWithOptions.apply(this, arguments);
|
||||
};
|
||||
|
||||
// And here is the point where we hijack the VSCode <-> TS communications
|
||||
// by adding ourselves in the middle. We locate everything that looks
|
||||
// like an absolute path of ours and normalize it.
|
||||
|
||||
const Session = tsserver.server.Session;
|
||||
const {onMessage: originalOnMessage, send: originalSend} = Session.prototype;
|
||||
let hostInfo = `unknown`;
|
||||
|
||||
Object.assign(Session.prototype, {
|
||||
onMessage(/** @type {string} */ message) {
|
||||
const parsedMessage = JSON.parse(message)
|
||||
|
||||
if (
|
||||
parsedMessage != null &&
|
||||
typeof parsedMessage === `object` &&
|
||||
parsedMessage.arguments &&
|
||||
typeof parsedMessage.arguments.hostInfo === `string`
|
||||
) {
|
||||
hostInfo = parsedMessage.arguments.hostInfo;
|
||||
if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK && process.env.VSCODE_IPC_HOOK.match(/Code\/1\.([1-5][0-9]|60)\./)) {
|
||||
hostInfo += ` <1.61`;
|
||||
}
|
||||
}
|
||||
|
||||
return originalOnMessage.call(this, JSON.stringify(parsedMessage, (key, value) => {
|
||||
return typeof value === `string` ? fromEditorPath(value) : value;
|
||||
}));
|
||||
},
|
||||
|
||||
send(/** @type {any} */ msg) {
|
||||
return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => {
|
||||
return typeof value === `string` ? toEditorPath(value) : value;
|
||||
})));
|
||||
}
|
||||
});
|
||||
|
||||
return tsserver;
|
||||
};
|
||||
|
||||
if (existsSync(absPnpApiPath)) {
|
||||
if (!process.versions.pnp) {
|
||||
// Setup the environment to be able to require typescript/lib/tsserver.js
|
||||
require(absPnpApiPath).setup();
|
||||
}
|
||||
}
|
||||
|
||||
// Defer to the real typescript/lib/tsserver.js your application uses
|
||||
module.exports = moduleWrapper(absRequire(`typescript/lib/tsserver.js`));
|
||||
184
.yarn/sdks/typescript/lib/tsserverlibrary.js
vendored
184
.yarn/sdks/typescript/lib/tsserverlibrary.js
vendored
@@ -1,184 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const {existsSync} = require(`fs`);
|
||||
const {createRequire, createRequireFromPath} = require(`module`);
|
||||
const {resolve} = require(`path`);
|
||||
|
||||
const relPnpApiPath = "../../../../.pnp.cjs";
|
||||
|
||||
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
|
||||
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
|
||||
|
||||
const moduleWrapper = tsserver => {
|
||||
if (!process.versions.pnp) {
|
||||
return tsserver;
|
||||
}
|
||||
|
||||
const {isAbsolute} = require(`path`);
|
||||
const pnpApi = require(`pnpapi`);
|
||||
|
||||
const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//);
|
||||
const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`);
|
||||
|
||||
const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => {
|
||||
return `${locator.name}@${locator.reference}`;
|
||||
}));
|
||||
|
||||
// VSCode sends the zip paths to TS using the "zip://" prefix, that TS
|
||||
// doesn't understand. This layer makes sure to remove the protocol
|
||||
// before forwarding it to TS, and to add it back on all returned paths.
|
||||
|
||||
function toEditorPath(str) {
|
||||
// We add the `zip:` prefix to both `.zip/` paths and virtual paths
|
||||
if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) {
|
||||
// We also take the opportunity to turn virtual paths into physical ones;
|
||||
// this makes it much easier to work with workspaces that list peer
|
||||
// dependencies, since otherwise Ctrl+Click would bring us to the virtual
|
||||
// file instances instead of the real ones.
|
||||
//
|
||||
// We only do this to modules owned by the the dependency tree roots.
|
||||
// This avoids breaking the resolution when jumping inside a vendor
|
||||
// with peer dep (otherwise jumping into react-dom would show resolution
|
||||
// errors on react).
|
||||
//
|
||||
const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str;
|
||||
if (resolved) {
|
||||
const locator = pnpApi.findPackageLocator(resolved);
|
||||
if (locator && dependencyTreeRoots.has(`${locator.name}@${locator.reference}`)) {
|
||||
str = resolved;
|
||||
}
|
||||
}
|
||||
|
||||
str = normalize(str);
|
||||
|
||||
if (str.match(/\.zip\//)) {
|
||||
switch (hostInfo) {
|
||||
// Absolute VSCode `Uri.fsPath`s need to start with a slash.
|
||||
// VSCode only adds it automatically for supported schemes,
|
||||
// so we have to do it manually for the `zip` scheme.
|
||||
// The path needs to start with a caret otherwise VSCode doesn't handle the protocol
|
||||
//
|
||||
// Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910
|
||||
//
|
||||
// Update Oct 8 2021: VSCode changed their format in 1.61.
|
||||
// Before | ^zip:/c:/foo/bar.zip/package.json
|
||||
// After | ^/zip//c:/foo/bar.zip/package.json
|
||||
//
|
||||
case `vscode <1.61`: {
|
||||
str = `^zip:${str}`;
|
||||
} break;
|
||||
|
||||
case `vscode`: {
|
||||
str = `^/zip/${str}`;
|
||||
} break;
|
||||
|
||||
// To make "go to definition" work,
|
||||
// We have to resolve the actual file system path from virtual path
|
||||
// and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip)
|
||||
case `coc-nvim`: {
|
||||
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
|
||||
str = resolve(`zipfile:${str}`);
|
||||
} break;
|
||||
|
||||
// Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server)
|
||||
// We have to resolve the actual file system path from virtual path,
|
||||
// everything else is up to neovim
|
||||
case `neovim`: {
|
||||
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
|
||||
str = `zipfile:${str}`;
|
||||
} break;
|
||||
|
||||
default: {
|
||||
str = `zip:${str}`;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
function fromEditorPath(str) {
|
||||
switch (hostInfo) {
|
||||
case `coc-nvim`:
|
||||
case `neovim`: {
|
||||
str = str.replace(/\.zip::/, `.zip/`);
|
||||
// The path for coc-nvim is in format of /<pwd>/zipfile:/<pwd>/.yarn/...
|
||||
// So in order to convert it back, we use .* to match all the thing
|
||||
// before `zipfile:`
|
||||
return process.platform === `win32`
|
||||
? str.replace(/^.*zipfile:\//, ``)
|
||||
: str.replace(/^.*zipfile:/, ``);
|
||||
} break;
|
||||
|
||||
case `vscode`:
|
||||
default: {
|
||||
return process.platform === `win32`
|
||||
? str.replace(/^\^?(zip:|\/zip)\/+/, ``)
|
||||
: str.replace(/^\^?(zip:|\/zip)\/+/, `/`);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
// Force enable 'allowLocalPluginLoads'
|
||||
// TypeScript tries to resolve plugins using a path relative to itself
|
||||
// which doesn't work when using the global cache
|
||||
// https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238
|
||||
// VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but
|
||||
// TypeScript already does local loads and if this code is running the user trusts the workspace
|
||||
// https://github.com/microsoft/vscode/issues/45856
|
||||
const ConfiguredProject = tsserver.server.ConfiguredProject;
|
||||
const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype;
|
||||
ConfiguredProject.prototype.enablePluginsWithOptions = function() {
|
||||
this.projectService.allowLocalPluginLoads = true;
|
||||
return originalEnablePluginsWithOptions.apply(this, arguments);
|
||||
};
|
||||
|
||||
// And here is the point where we hijack the VSCode <-> TS communications
|
||||
// by adding ourselves in the middle. We locate everything that looks
|
||||
// like an absolute path of ours and normalize it.
|
||||
|
||||
const Session = tsserver.server.Session;
|
||||
const {onMessage: originalOnMessage, send: originalSend} = Session.prototype;
|
||||
let hostInfo = `unknown`;
|
||||
|
||||
Object.assign(Session.prototype, {
|
||||
onMessage(/** @type {string} */ message) {
|
||||
const parsedMessage = JSON.parse(message)
|
||||
|
||||
if (
|
||||
parsedMessage != null &&
|
||||
typeof parsedMessage === `object` &&
|
||||
parsedMessage.arguments &&
|
||||
typeof parsedMessage.arguments.hostInfo === `string`
|
||||
) {
|
||||
hostInfo = parsedMessage.arguments.hostInfo;
|
||||
if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK && process.env.VSCODE_IPC_HOOK.match(/Code\/1\.([1-5][0-9]|60)\./)) {
|
||||
hostInfo += ` <1.61`;
|
||||
}
|
||||
}
|
||||
|
||||
return originalOnMessage.call(this, JSON.stringify(parsedMessage, (key, value) => {
|
||||
return typeof value === `string` ? fromEditorPath(value) : value;
|
||||
}));
|
||||
},
|
||||
|
||||
send(/** @type {any} */ msg) {
|
||||
return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => {
|
||||
return typeof value === `string` ? toEditorPath(value) : value;
|
||||
})));
|
||||
}
|
||||
});
|
||||
|
||||
return tsserver;
|
||||
};
|
||||
|
||||
if (existsSync(absPnpApiPath)) {
|
||||
if (!process.versions.pnp) {
|
||||
// Setup the environment to be able to require typescript/lib/tsserverlibrary.js
|
||||
require(absPnpApiPath).setup();
|
||||
}
|
||||
}
|
||||
|
||||
// Defer to the real typescript/lib/tsserverlibrary.js your application uses
|
||||
module.exports = moduleWrapper(absRequire(`typescript/lib/tsserverlibrary.js`));
|
||||
20
.yarn/sdks/typescript/lib/typescript.js
vendored
20
.yarn/sdks/typescript/lib/typescript.js
vendored
@@ -1,20 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const {existsSync} = require(`fs`);
|
||||
const {createRequire, createRequireFromPath} = require(`module`);
|
||||
const {resolve} = require(`path`);
|
||||
|
||||
const relPnpApiPath = "../../../../.pnp.cjs";
|
||||
|
||||
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
|
||||
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
|
||||
|
||||
if (existsSync(absPnpApiPath)) {
|
||||
if (!process.versions.pnp) {
|
||||
// Setup the environment to be able to require typescript/lib/typescript.js
|
||||
require(absPnpApiPath).setup();
|
||||
}
|
||||
}
|
||||
|
||||
// Defer to the real typescript/lib/typescript.js your application uses
|
||||
module.exports = absRequire(`typescript/lib/typescript.js`);
|
||||
6
.yarn/sdks/typescript/package.json
vendored
6
.yarn/sdks/typescript/package.json
vendored
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"name": "typescript",
|
||||
"version": "4.4.3-sdk",
|
||||
"main": "./lib/typescript.js",
|
||||
"type": "commonjs"
|
||||
}
|
||||
81
.yarnrc.yml
81
.yarnrc.yml
@@ -1,81 +0,0 @@
|
||||
enableTelemetry: false
|
||||
nodeLinker: "pnp"
|
||||
|
||||
packageExtensions:
|
||||
"@grafana/slate-react@0.22.10-grafana":
|
||||
peerDependencies:
|
||||
slate-react: ">=0.22.0"
|
||||
"@mdx-js/loader@1.6.22":
|
||||
peerDependencies:
|
||||
react: 17.0.1
|
||||
"@storybook/addon-essentials@6.3.7":
|
||||
peerDependencies:
|
||||
"@storybook/components": 6.3.7
|
||||
"@storybook/core-events": 6.3.7
|
||||
"@storybook/theming": 6.3.7
|
||||
"@storybook/addon-knobs@6.3.0":
|
||||
dependencies:
|
||||
copy-to-clipboard: ^3.3.1
|
||||
"@storybook/core-server@6.3.7":
|
||||
peerDependencies:
|
||||
"@babel/core": ^7.0.0
|
||||
"@storybook/core@6.3.7":
|
||||
peerDependencies:
|
||||
"@babel/core": ^7.0.0
|
||||
"@storybook/manager-webpack5": 6.3.7
|
||||
webpack: 5.51.1
|
||||
"@storybook/csf-tools@6.3.7":
|
||||
peerDependencies:
|
||||
"@babel/core": ^7.0.0
|
||||
"@storybook/react@6.3.7":
|
||||
peerDependencies:
|
||||
"@storybook/manager-webpack5": 6.3.7
|
||||
doctrine@3.0.0:
|
||||
dependencies:
|
||||
assert: 2.0.0
|
||||
moveable@0.26.0:
|
||||
dependencies:
|
||||
"@daybrush/utils": 1.6.0
|
||||
framework-utils: ^1.1.0
|
||||
react-simple-compat: 1.2.1
|
||||
rc-time-picker@3.7.3:
|
||||
peerDependencies:
|
||||
react: 17.0.1
|
||||
react-dom: 17.0.1
|
||||
rc-trigger@2.6.5:
|
||||
peerDependencies:
|
||||
react: 17.0.1
|
||||
react-dom: 17.0.1
|
||||
react-compat-moveable@0.14.0:
|
||||
dependencies:
|
||||
"@egjs/agent": ^2.2.1
|
||||
"@egjs/children-differ": ^1.0.1
|
||||
"@scena/matrix": 1.1.1
|
||||
css-to-mat: ^1.0.3
|
||||
gesto: ^1.4.0
|
||||
overlap-area: ^1.0.0
|
||||
peerDependencies:
|
||||
framework-utils: ^1.1.0
|
||||
react-dev-utils@11.0.4:
|
||||
peerDependencies:
|
||||
typescript: 4.4.3
|
||||
webpack: 5.51.1
|
||||
react-docgen-typescript-loader@3.7.2:
|
||||
peerDependencies:
|
||||
webpack: 4.41.5
|
||||
react-icons@2.2.7:
|
||||
peerDependencies:
|
||||
prop-types: "*"
|
||||
react-resizable@3.0.4:
|
||||
peerDependencies:
|
||||
react-dom: 17.0.1
|
||||
|
||||
plugins:
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-typescript.cjs
|
||||
spec: "@yarnpkg/plugin-typescript"
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
|
||||
spec: "@yarnpkg/plugin-interactive-tools"
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-outdated.cjs
|
||||
spec: "https://mskelton.dev/yarn-outdated/v2"
|
||||
|
||||
yarnPath: .yarn/releases/yarn-3.1.0.cjs
|
||||
4323
CHANGELOG.md
4323
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
2256
CHANGELOG_ARCHIVE.md
2256
CHANGELOG_ARCHIVE.md
File diff suppressed because it is too large
Load Diff
@@ -19,22 +19,9 @@ For more ways to contribute, check out the [Open Source Guides](https://opensour
|
||||
|
||||
### 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.
|
||||
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.
|
||||
|
||||
#### Security issues
|
||||
|
||||
@@ -42,7 +29,7 @@ If you believe you've found a security vulnerability, please read our [security
|
||||
|
||||
### Suggest enhancements
|
||||
|
||||
If you have an idea of how to improve Grafana, submit an [enhancement request](https://github.com/grafana/grafana/discussions/new).
|
||||
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.
|
||||
|
||||
@@ -78,4 +65,4 @@ Before we can accept your pull request, you need to [sign our CLA](https://grafa
|
||||
- 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.
|
||||
- Look through the resources in the [contribute](https://github.com/grafana/grafana/tree/master/contribute) folder.
|
||||
|
||||
98
Dockerfile
98
Dockerfile
@@ -1,92 +1,76 @@
|
||||
FROM node:16-alpine3.14 as js-builder
|
||||
FROM node:12.19.0-alpine3.12 as js-builder
|
||||
|
||||
ENV NODE_OPTIONS=--max_old_space_size=8000
|
||||
WORKDIR /usr/src/app/
|
||||
|
||||
WORKDIR /grafana
|
||||
|
||||
COPY package.json yarn.lock .yarnrc.yml ./
|
||||
COPY .yarn .yarn
|
||||
COPY package.json yarn.lock ./
|
||||
COPY packages packages
|
||||
COPY plugins-bundled plugins-bundled
|
||||
|
||||
RUN yarn install
|
||||
RUN yarn install --pure-lockfile --no-progress
|
||||
|
||||
COPY tsconfig.json .eslintrc .editorconfig .browserslistrc .prettierrc.js ./
|
||||
COPY Gruntfile.js 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
|
||||
RUN ./node_modules/.bin/grunt build
|
||||
|
||||
FROM golang:1.17.3-alpine3.14 as go-builder
|
||||
FROM golang:1.15.1-alpine3.12 as go-builder
|
||||
|
||||
RUN apk add --no-cache gcc g++ make
|
||||
RUN apk add --no-cache gcc g++
|
||||
|
||||
WORKDIR /grafana
|
||||
WORKDIR $GOPATH/src/github.com/grafana/grafana
|
||||
|
||||
COPY go.mod go.sum embed.go Makefile build.go package.json ./
|
||||
COPY ./local/* ./local/
|
||||
COPY cue cue
|
||||
COPY packages/grafana-schema packages/grafana-schema
|
||||
COPY public/app/plugins public/app/plugins
|
||||
COPY pkg pkg
|
||||
COPY scripts scripts
|
||||
COPY cue.mod cue.mod
|
||||
COPY .bingo .bingo
|
||||
COPY go.mod go.sum ./
|
||||
|
||||
RUN go mod verify
|
||||
RUN make build-go
|
||||
|
||||
COPY pkg pkg
|
||||
COPY build.go package.json ./
|
||||
|
||||
RUN go run build.go build
|
||||
|
||||
# Final stage
|
||||
FROM alpine:3.14.3
|
||||
FROM alpine:3.12
|
||||
|
||||
LABEL maintainer="Grafana team <hello@grafana.com>"
|
||||
|
||||
ARG GF_UID="472"
|
||||
ARG GF_GID="0"
|
||||
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"
|
||||
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
|
||||
|
||||
RUN apk add --no-cache ca-certificates bash tzdata musl-utils
|
||||
RUN apk add --no-cache openssl ncurses-libs ncurses-terminfo-base --repository=http://dl-cdn.alpinelinux.org/alpine/edge/main
|
||||
RUN apk upgrade ncurses-libs ncurses-terminfo-base --repository=http://dl-cdn.alpinelinux.org/alpine/edge/main
|
||||
RUN apk info -vv | sort
|
||||
RUN apk add --no-cache ca-certificates bash tzdata && \
|
||||
apk add --no-cache openssl musl-utils
|
||||
|
||||
COPY conf ./conf
|
||||
|
||||
RUN if [ ! $(getent group "$GF_GID") ]; then \
|
||||
addgroup -S -g $GF_GID grafana; \
|
||||
fi
|
||||
RUN mkdir -p "$GF_PATHS_HOME/.aws" && \
|
||||
addgroup -S -g $GF_GID grafana && \
|
||||
adduser -S -u $GF_UID -G grafana grafana && \
|
||||
mkdir -p "$GF_PATHS_PROVISIONING/datasources" \
|
||||
"$GF_PATHS_PROVISIONING/dashboards" \
|
||||
"$GF_PATHS_PROVISIONING/notifiers" \
|
||||
"$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: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"
|
||||
|
||||
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 && \
|
||||
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"
|
||||
|
||||
COPY --from=go-builder /grafana/bin/*/grafana-server /grafana/bin/*/grafana-cli ./bin/
|
||||
COPY --from=js-builder /grafana/public ./public
|
||||
COPY --from=js-builder /grafana/tools ./tools
|
||||
COPY --from=go-builder /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=js-builder /usr/src/app/public ./public
|
||||
COPY --from=js-builder /usr/src/app/tools ./tools
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
|
||||
@@ -1,41 +1,33 @@
|
||||
FROM node:16-alpine3.14 as js-builder
|
||||
|
||||
ENV NODE_OPTIONS=--max_old_space_size=8000
|
||||
FROM node:12.19.0-slim AS js-builder
|
||||
|
||||
WORKDIR /usr/src/app/
|
||||
|
||||
COPY package.json yarn.lock ./
|
||||
COPY packages packages
|
||||
COPY .yarnrc.yml ./
|
||||
COPY .yarn .yarn
|
||||
COPY plugins-bundled plugins-bundled
|
||||
|
||||
RUN yarn install
|
||||
RUN yarn install --pure-lockfile
|
||||
|
||||
COPY tsconfig.json .eslintrc .editorconfig .browserslistrc .prettierrc.js ./
|
||||
COPY Gruntfile.js 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
|
||||
RUN ./node_modules/.bin/grunt build
|
||||
|
||||
FROM golang:1.17.3 AS go-builder
|
||||
FROM golang:1.15.1 AS go-builder
|
||||
|
||||
WORKDIR /src/grafana
|
||||
|
||||
COPY go.mod go.sum embed.go ./
|
||||
COPY Makefile build.go package.json ./
|
||||
COPY .bingo .bingo
|
||||
COPY pkg pkg/
|
||||
COPY cue cue/
|
||||
COPY cue.mod cue.mod/
|
||||
COPY packages/grafana-schema packages/grafana-schema/
|
||||
COPY public/app/plugins public/app/plugins/
|
||||
COPY go.mod go.sum ./
|
||||
|
||||
RUN go mod verify
|
||||
RUN make build-go
|
||||
|
||||
COPY build.go package.json ./
|
||||
COPY pkg pkg/
|
||||
|
||||
RUN go run build.go build
|
||||
|
||||
FROM ubuntu:20.04
|
||||
|
||||
@@ -66,8 +58,6 @@ RUN mkdir -p "$GF_PATHS_HOME/.aws" && \
|
||||
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" && \
|
||||
@@ -76,7 +66,7 @@ RUN mkdir -p "$GF_PATHS_HOME/.aws" && \
|
||||
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=go-builder /src/grafana/bin/linux-amd64/grafana-server /src/grafana/bin/linux-amd64/grafana-cli bin/
|
||||
COPY --from=js-builder /usr/src/app/public public
|
||||
COPY --from=js-builder /usr/src/app/tools tools
|
||||
|
||||
|
||||
@@ -78,7 +78,6 @@ The current team members are:
|
||||
- Diana Sarlinska ([Grafana Labs](https://grafana.com/))
|
||||
- Dominik Prokop ([Grafana Labs](https://grafana.com/))
|
||||
- Emil Tullstedt ([Grafana Labs](https://grafana.com/))
|
||||
- Erik Sundell ([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/))
|
||||
@@ -103,8 +102,6 @@ The current team members are:
|
||||
- Tobias Skarhed ([Grafana Labs](https://grafana.com/))
|
||||
- Torkel Ödegaard ([Grafana Labs](https://grafana.com/))
|
||||
- Utkarsh Bhatnagar ([Tinder](https://www.tinder.com/))
|
||||
- Will Browne ([Grafana Labs](https://grafana.com/))
|
||||
- Zoltán Bedi ([Grafana Labs](https://grafana.com/))
|
||||
|
||||
### Maintainers
|
||||
|
||||
@@ -201,8 +198,8 @@ The ex-member is
|
||||
|
||||
If needed, we reserve the right to publicly announce removal.
|
||||
|
||||
[coc]: https://github.com/grafana/grafana/blob/main/CODE_OF_CONDUCT.md
|
||||
[coc]: https://github.com/grafana/grafana/blob/master/CODE_OF_CONDUCT.md
|
||||
[devs]: https://groups.google.com/forum/#!forum/grafana-developers
|
||||
[maintainers]: https://github.com/grafana/grafana/blob/main/MAINTAINERS.md
|
||||
[maintainers]: https://github.com/grafana/grafana/blob/master/MAINTAINERS.md
|
||||
[rough]: https://tools.ietf.org/html/rfc7282
|
||||
[team]: https://groups.google.com/forum/#!forum/grafana-team
|
||||
|
||||
66
Gruntfile.js
Normal file
66
Gruntfile.js
Normal file
@@ -0,0 +1,66 @@
|
||||
'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'),
|
||||
enterprise: false,
|
||||
libc: null,
|
||||
};
|
||||
|
||||
if (grunt.option('platform')) {
|
||||
config.platform = grunt.option('platform');
|
||||
}
|
||||
|
||||
if (grunt.option('enterprise')) {
|
||||
config.enterprise = true;
|
||||
}
|
||||
|
||||
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';
|
||||
}
|
||||
}
|
||||
|
||||
if (grunt.option('libc')) {
|
||||
config.libc = grunt.option('libc');
|
||||
}
|
||||
|
||||
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);
|
||||
};
|
||||
@@ -4,7 +4,7 @@ The main goal of issue triage is to categorize all incoming Grafana issues and m
|
||||
|
||||
> **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.
|
||||
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:
|
||||
|
||||
@@ -18,7 +18,6 @@ If you don't have the knowledge or time to code, consider helping with triage. T
|
||||
## Simplified flowchart diagram of the issue triage process
|
||||
|
||||
<!-- https://textik.com/#610afa78553def29 -->
|
||||
|
||||
```
|
||||
+--------------------------+
|
||||
+----------------+ New issue opened/ |
|
||||
@@ -77,16 +76,15 @@ Instructions for setting up filters in Gmail can be found [here](#setting-up-gma
|
||||
|
||||
## 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.
|
||||
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.
|
||||
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
|
||||
@@ -172,12 +170,10 @@ If it's not perfectly clear that it's an actual bug, quickly try to reproduce it
|
||||
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`.
|
||||
|
||||
@@ -199,7 +195,6 @@ Second, label the issue `type/docs` and at least one `area/*` or `datasource/*`
|
||||
**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.
|
||||
|
||||
@@ -304,14 +299,12 @@ For some other combinations it may not be possible at all for a maintainer to se
|
||||
|
||||
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
|
||||
## 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)
|
||||
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/master/.github/commands.json). Or in other [GitHub Actions](https://github.com/grafana/grafana/tree/master/.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)
|
||||
* Add /duplicate `#<issue number>` to have Grafana label & close issue with an appropriate message.
|
||||
* Add `type/question` and the bot will close it with an appropriate message.
|
||||
|
||||
## External PRs
|
||||
|
||||
@@ -329,7 +322,6 @@ Part of issue triage should also be triaging of external PRs. Main goal should b
|
||||
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
|
||||
@@ -338,7 +330,6 @@ This may be setup by personal preference, but here's a working configuration for
|
||||
6. Create filters
|
||||
|
||||
This will give you a structure of labels in the sidebar similar to the following:
|
||||
|
||||
```
|
||||
- Inbox
|
||||
...
|
||||
|
||||
863
LICENSE
863
LICENSE
@@ -1,661 +1,202 @@
|
||||
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/>.
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2015 Grafana Labs
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
28
LICENSING.md
28
LICENSING.md
@@ -1,28 +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 directories and their subdirectories 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/
|
||||
```
|
||||
|
||||
The following directories and their subdirectories are the original upstream licenses:
|
||||
|
||||
```
|
||||
public/vendor/
|
||||
```
|
||||
57
Makefile
57
Makefile
@@ -2,14 +2,11 @@
|
||||
##
|
||||
## For more information, refer to https://suva.sh/posts/well-documented-makefiles/
|
||||
|
||||
WIRE_TAGS = "oss"
|
||||
|
||||
-include local/Makefile
|
||||
include .bingo/Variables.mk
|
||||
|
||||
.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 gen-ts test run run-frontend clean devenv devenv-down protobuf drone help
|
||||
.PHONY: all deps-go deps-js deps build-go build-server build-cli build-js build build-docker-dev build-docker-full lint-go revive golangci-lint tidy-check test-go test-js test run run-frontend clean devenv devenv-down revive-strict protobuf help
|
||||
|
||||
GO = go
|
||||
GO = GO111MODULE=on go
|
||||
GO_FILES ?= ./pkg/...
|
||||
SH_FILES ?= $(shell find ./scripts -name *.sh)
|
||||
|
||||
@@ -26,15 +23,11 @@ deps: deps-js ## Install all dependencies.
|
||||
|
||||
node_modules: package.json yarn.lock ## Install node modules.
|
||||
@echo "install frontend dependencies"
|
||||
YARN_ENABLE_PROGRESS_BARS=false yarn install --immutable
|
||||
yarn install --pure-lockfile --no-progress
|
||||
|
||||
##@ Building
|
||||
|
||||
gen-go: $(WIRE)
|
||||
@echo "generate go files"
|
||||
$(WIRE) gen -tags $(WIRE_TAGS) ./pkg/server ./pkg/cmd/grafana-cli/runner
|
||||
|
||||
build-go: gen-go ## Build all Go binaries.
|
||||
build-go: ## Build all Go binaries.
|
||||
@echo "build go files"
|
||||
$(GO) run build.go build
|
||||
|
||||
@@ -43,7 +36,7 @@ build-server: ## Build Grafana server.
|
||||
$(GO) run build.go build-server
|
||||
|
||||
build-cli: ## Build Grafana CLI application.
|
||||
@echo "build grafana-cli"
|
||||
@echo "build in CI environment"
|
||||
$(GO) run build.go build-cli
|
||||
|
||||
build-js: ## Build frontend assets.
|
||||
@@ -58,7 +51,7 @@ scripts/go/bin/bra: scripts/go/go.mod
|
||||
$(GO) build -o ./bin/bra github.com/unknwon/bra
|
||||
|
||||
run: scripts/go/bin/bra ## Build and run web server on filesystem changes.
|
||||
@scripts/go/bin/bra run
|
||||
@GO111MODULE=on scripts/go/bin/bra run
|
||||
|
||||
run-frontend: deps-js ## Fetch js dependencies and watch frontend for rebuild
|
||||
yarn start
|
||||
@@ -76,6 +69,22 @@ test-js: ## Run tests for frontend.
|
||||
test: test-go test-js ## Run all tests.
|
||||
|
||||
##@ Linting
|
||||
|
||||
scripts/go/bin/revive: scripts/go/go.mod
|
||||
@cd scripts/go; \
|
||||
$(GO) build -o ./bin/revive github.com/mgechev/revive
|
||||
|
||||
revive: scripts/go/bin/revive
|
||||
@echo "lint via revive"
|
||||
@scripts/go/bin/revive \
|
||||
-formatter stylish \
|
||||
-config ./scripts/go/configs/revive.toml \
|
||||
$(GO_FILES)
|
||||
|
||||
revive-strict: scripts/go/bin/revive
|
||||
@echo "lint via revive (strict)"
|
||||
@scripts/revive-strict scripts/go/bin/revive
|
||||
|
||||
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
|
||||
@@ -86,7 +95,11 @@ golangci-lint: scripts/go/bin/golangci-lint
|
||||
--config ./scripts/go/configs/.golangci.toml \
|
||||
$(GO_FILES)
|
||||
|
||||
lint-go: golangci-lint ## Run all code checks for backend. You can use GO_FILES to specify exact files to check
|
||||
tidy-check:
|
||||
@echo "check whether go.mod and go.sum are consistent"
|
||||
@scripts/tidy-check.sh
|
||||
|
||||
lint-go: golangci-lint revive revive-strict tidy-check # 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.
|
||||
@@ -98,7 +111,7 @@ shellcheck: $(SH_FILES) ## Run checks for shell scripts.
|
||||
build-docker-dev: ## Build Docker image for development (fast).
|
||||
@echo "build development container"
|
||||
@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 latest
|
||||
$(GO) run build.go -goos linux -pkg-arch amd64 ${OPT} build pkg-archive latest
|
||||
cp dist/grafana-latest.linux-x64.tar.gz packaging/docker
|
||||
cd packaging/docker && docker build --tag grafana/grafana:dev .
|
||||
|
||||
@@ -147,19 +160,5 @@ clean: ## Clean up intermediate build artifacts.
|
||||
rm -rf node_modules
|
||||
rm -rf public/build
|
||||
|
||||
gen-ts:
|
||||
@echo "generating TypeScript definitions"
|
||||
go get github.com/tkrajina/typescriptify-golang-structs/typescriptify@v0.1.7
|
||||
tscriptify -interface -package=github.com/grafana/grafana/pkg/services/live/pipeline -import="import { FieldConfig } from '@grafana/data'" -target=public/app/features/live/pipeline/models.gen.ts pkg/services/live/pipeline/config.go
|
||||
go mod tidy
|
||||
|
||||
# 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)
|
||||
$(DRONE) starlark --format
|
||||
$(DRONE) lint .drone.yml --trusted
|
||||
$(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)
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
Copyright 2014-2021 Grafana Labs
|
||||
|
||||
This software is based on Kibana:
|
||||
Copyright 2014-2018 Grafana Labs
|
||||
|
||||
This software is based on Kibana:
|
||||
Copyright 2012-2013 Elasticsearch BV
|
||||
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
# 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
|
||||
upgrading Grafana please check here before creating an issue.
|
||||
upgrading Grafana please check here before creating an issue.
|
||||
|
||||
## Plugin development resources
|
||||
|
||||
- [Grafana plugin developer guide](https://grafana.com/docs/grafana/latest/developers/plugins/)
|
||||
- [Grafana plugin developer 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
|
||||
|
||||
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
|
||||
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.
|
||||
for built-in plugins and 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.
|
||||
If you think we missed exposing a crucial lib or Grafana component let us know by opening an issue.
|
||||
|
||||
### Deprecated components
|
||||
### 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>`
|
||||
|
||||
17
README.md
17
README.md
@@ -3,12 +3,12 @@
|
||||
The open-source platform for monitoring and observability.
|
||||
|
||||
[](LICENSE)
|
||||
[](https://drone.grafana.net/grafana/grafana)
|
||||
[](https://circleci.com/gh/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:
|
||||
|
||||
- **Visualize:** Fast and flexible client side graphs with a multitude of options. Panel plugins offer many different ways to visualize metrics and logs.
|
||||
- **Visualize:** Fast and flexible client side graphs with a multitude of options. Panel plugins for many different way 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.
|
||||
@@ -30,18 +30,17 @@ The Grafana documentation is available at [grafana.com/docs](https://grafana.com
|
||||
|
||||
If you're interested in contributing to the Grafana project:
|
||||
|
||||
- Start by reading the [Contributing guide](https://github.com/grafana/grafana/blob/HEAD/CONTRIBUTING.md).
|
||||
- Learn how to set up your local environment, in our [Developer guide](https://github.com/grafana/grafana/blob/HEAD/contribute/developer-guide.md).
|
||||
- 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).
|
||||
|
||||
## Get involved
|
||||
|
||||
- Follow [@grafana on Twitter](https://twitter.com/grafana/).
|
||||
- Read and subscribe to the [Grafana blog](https://grafana.com/blog/).
|
||||
- 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](https://slack.grafana.com) team.
|
||||
- For general discussions, join us on the [official Slack](http://slack.raintank.io/) team.
|
||||
|
||||
## License
|
||||
|
||||
Grafana is distributed under [AGPL-3.0-only](LICENSE). For Apache-2.0 exceptions, see [LICENSING.md](https://github.com/grafana/grafana/blob/HEAD/LICENSING.md).
|
||||
Grafana is distributed under the [Apache 2.0 License](https://github.com/grafana/grafana/blob/master/LICENSE).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Roadmap
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
To view the Roadmap, go to the Issues tab on GitHub. There you will find three roadmap issues pinned at the top.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# 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.
|
||||
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
|
||||
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).
|
||||
|
||||
@@ -15,6 +15,6 @@ Grafana Labs will send you a response indicating the next steps in handling your
|
||||
## 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.
|
||||
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).
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
# 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:**
|
||||
|
||||
**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.
|
||||
|
||||
@@ -4,14 +4,14 @@ Upgrading Go or Node.js requires making changes in many different files. See bel
|
||||
|
||||
## Go
|
||||
|
||||
- Drone
|
||||
- CircleCi
|
||||
- `grafana/build-container`
|
||||
- Appveyor
|
||||
- Dockerfile
|
||||
|
||||
## Node.js
|
||||
|
||||
- Drone
|
||||
- CircleCI
|
||||
- `grafana/build-container`
|
||||
- Appveyor
|
||||
- Dockerfile
|
||||
@@ -20,29 +20,28 @@ Upgrading Go or Node.js requires making changes in many different files. See bel
|
||||
|
||||
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
|
||||
go get example.com/some/module/pkg
|
||||
# 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.
|
||||
go get example.com/some/module/pkg@vX.Y.Z
|
||||
GO111MODULE=on go get example.com/some/module/pkg@vX.Y.Z
|
||||
```
|
||||
|
||||
Tidy up the `go.mod` and `go.sum` files:
|
||||
|
||||
```bash
|
||||
go mod tidy
|
||||
# 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.
|
||||
|
||||
To understand what the actual dependencies of `grafana-server` are, one could run it with `-vv` flag. This might produce an output, different from `go.mod` contents and `-vv` option is the source of truth here. It lists the modules _compiled_ into the executable, while `go.mod` lists also test and weak transitive dependencies (modules, used in some package, which is not in use by itself). If you are interested in reporting a vulnerability in a dependency module - please consult `-vv` output, maybe the "dependency" is not a dependency as such.
|
||||
|
||||
### Upgrading dependencies
|
||||
|
||||
If you need to upgrade a direct or indirect dependency, you can do it like so, $MODULE being the dependency in question: `go get -u $MODULE`. The corresponding entry in go.mod should then have the version you specified; if it's an indirect dependency, the entry should have the `// indirect` comment. Follow this by executing `go mod tidy`, to ensure that go.mod and go.sum are up to date. If the indirect dependency turns out to not be used (transitively) by any of our packages, `go mod tidy` will actually strip it from go.mod. In that case, you can just ignore it since it isn't used in the end.
|
||||
|
||||
## Node.js dependencies
|
||||
|
||||
Updated using `yarn`.
|
||||
@@ -51,9 +50,9 @@ Updated using `yarn`.
|
||||
|
||||
## Where to make changes
|
||||
|
||||
### Drone
|
||||
### CircleCI
|
||||
|
||||
Our CI builds run on Drone.
|
||||
Our builds run on CircleCI through our build script.
|
||||
|
||||
#### Files
|
||||
|
||||
@@ -67,9 +66,9 @@ Our CI builds run on Drone.
|
||||
|
||||
### grafana/build-container
|
||||
|
||||
The main build steps (in Drone) happen using a custom Docker image that comes pre-baked with some of the necessary dependencies.
|
||||
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)
|
||||
Link: [grafana/build-container](https://github.com/grafana/grafana/tree/master/scripts/build/ci-build)
|
||||
|
||||
#### Dependencies
|
||||
|
||||
@@ -80,7 +79,7 @@ Link: [grafana/build-container](https://github.com/grafana/grafana/tree/main/scr
|
||||
|
||||
### Appveyor
|
||||
|
||||
Main and release builds trigger test runs on Appveyors build environment so that tests will run on Windows.
|
||||
Master and release builds trigger test runs on Appveyors build environment so that tests will run on Windows.
|
||||
|
||||
#### Files:
|
||||
|
||||
|
||||
24
WORKFLOW.md
24
WORKFLOW.md
@@ -12,8 +12,7 @@ Team members and their access to repositories is maintained through [GitHub team
|
||||
|
||||
## 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:
|
||||
|
||||
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 master 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
|
||||
@@ -24,8 +23,7 @@ Significant changes MUST be discussed and agreed upon with the relevant subsyste
|
||||
## 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.
|
||||
|
||||
Commits MUST be merged into master using PRs. They MUST NOT be merged into master 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
|
||||
@@ -35,18 +33,11 @@ Commits MUST be merged into main using PRs. They MUST NOT be merged into main di
|
||||
- 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
|
||||
@@ -54,8 +45,7 @@ Backport PRs are also needed during the beta period to get fixes into the stable
|
||||
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.
|
||||
- Master 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.
|
||||
@@ -65,15 +55,15 @@ In particular, we found that the following principles match how we work:
|
||||
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.
|
||||
- MAJOR release branches MUST be based on master.
|
||||
- MINOR release branches MUST be based on master.
|
||||
- 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
|
||||
PRs intended for inclusion in the next PATCH release MUST be labeled with `cherry-pick-needed` so they can be picked up by automated release tooling.
|
||||
|
||||
Releases follow the following cadence
|
||||
- MAJOR: Yearly
|
||||
- MINOR: Every 4-6 weeks
|
||||
- PATCH: As needed
|
||||
|
||||
688
build.go
688
build.go
@@ -3,14 +3,698 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/build"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
"github.com/grafana/grafana/pkg/build"
|
||||
const (
|
||||
windows = "windows"
|
||||
linux = "linux"
|
||||
)
|
||||
|
||||
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"
|
||||
// deb & rpm does not support semver so have to handle their version a little differently
|
||||
linuxPackageVersion string = "v1"
|
||||
linuxPackageIteration string = ""
|
||||
race bool
|
||||
workingDir string
|
||||
includeBuildId bool = true
|
||||
buildId string = "0"
|
||||
serverBinary string = "grafana-server"
|
||||
cliBinary string = "grafana-cli"
|
||||
binaries []string = []string{serverBinary, cliBinary}
|
||||
isDev bool = false
|
||||
enterprise bool = false
|
||||
skipRpmGen bool = false
|
||||
skipDebGen bool = false
|
||||
printGenVersion bool = false
|
||||
)
|
||||
|
||||
func main() {
|
||||
log.SetOutput(os.Stdout)
|
||||
log.SetFlags(0)
|
||||
os.Exit(build.RunCmd())
|
||||
|
||||
var buildIdRaw string
|
||||
|
||||
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.BoolVar(&cgo, "cgo-enabled", cgo, "Enable cgo")
|
||||
flag.StringVar(&pkgArch, "pkg-arch", "", "PKG ARCH")
|
||||
flag.BoolVar(&race, "race", race, "Use race detector")
|
||||
flag.BoolVar(&includeBuildId, "includeBuildId", includeBuildId, "IncludeBuildId in package name")
|
||||
flag.BoolVar(&enterprise, "enterprise", enterprise, "Build enterprise version of Grafana")
|
||||
flag.StringVar(&buildIdRaw, "buildId", "0", "Build ID 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
|
||||
}
|
||||
|
||||
log.Printf("Version: %s, Linux Version: %s, Package Iteration: %s\n", version, linuxPackageVersion, linuxPackageIteration)
|
||||
|
||||
if flag.NArg() == 0 {
|
||||
log.Println("Usage: go run build.go build")
|
||||
return
|
||||
}
|
||||
|
||||
workingDir, _ = os.Getwd()
|
||||
|
||||
for _, cmd := range flag.Args() {
|
||||
switch cmd {
|
||||
case "setup":
|
||||
setup()
|
||||
|
||||
case "build-srv", "build-server":
|
||||
clean()
|
||||
doBuild("grafana-server", "./pkg/cmd/grafana-server", []string{})
|
||||
|
||||
case "build-cli":
|
||||
clean()
|
||||
doBuild("grafana-cli", "./pkg/cmd/grafana-cli", []string{})
|
||||
|
||||
case "build":
|
||||
//clean()
|
||||
for _, binary := range binaries {
|
||||
doBuild(binary, "./pkg/cmd/"+binary, []string{})
|
||||
}
|
||||
|
||||
case "build-frontend":
|
||||
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-archive":
|
||||
grunt(gruntBuildArg("package")...)
|
||||
|
||||
case "pkg-rpm":
|
||||
grunt(gruntBuildArg("release")...)
|
||||
createRpmPackages()
|
||||
|
||||
case "pkg-deb":
|
||||
grunt(gruntBuildArg("release")...)
|
||||
createDebPackages()
|
||||
|
||||
case "sha-dist":
|
||||
shaFilesInDist()
|
||||
|
||||
case "latest":
|
||||
makeLatestDistCopies()
|
||||
|
||||
case "clean":
|
||||
clean()
|
||||
|
||||
default:
|
||||
log.Fatalf("Unknown command %q", cmd)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func makeLatestDistCopies() {
|
||||
files, err := ioutil.ReadDir("dist")
|
||||
if err != nil {
|
||||
log.Fatalf("failed to create latest copies. Cannot read from /dist")
|
||||
}
|
||||
|
||||
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",
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
for extension, fullName := range latestMapping {
|
||||
if strings.HasSuffix(file.Name(), extension) {
|
||||
runError("cp", path.Join("dist", file.Name()), fullName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func readVersionFromPackageJson() {
|
||||
reader, err := os.Open("package.json")
|
||||
if err != nil {
|
||||
log.Fatal("Failed to open package.json")
|
||||
return
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
jsonObj := map[string]interface{}{}
|
||||
jsonParser := json.NewDecoder(reader)
|
||||
|
||||
if err := jsonParser.Decode(&jsonObj); err != nil {
|
||||
log.Fatal("Failed to decode package.json")
|
||||
}
|
||||
|
||||
version = jsonObj["version"].(string)
|
||||
linuxPackageVersion = version
|
||||
linuxPackageIteration = ""
|
||||
|
||||
// handle pre version stuff (deb / rpm does not support semver)
|
||||
parts := strings.Split(version, "-")
|
||||
|
||||
if len(parts) > 1 {
|
||||
linuxPackageVersion = parts[0]
|
||||
linuxPackageIteration = parts[1]
|
||||
}
|
||||
|
||||
// add timestamp to iteration
|
||||
if includeBuildId {
|
||||
if buildId != "0" {
|
||||
linuxPackageIteration = fmt.Sprintf("%s%s", buildId, linuxPackageIteration)
|
||||
} else {
|
||||
linuxPackageIteration = fmt.Sprintf("%d%s", time.Now().Unix(), linuxPackageIteration)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type linuxPackageOptions struct {
|
||||
packageType string
|
||||
packageArch string
|
||||
homeDir string
|
||||
homeBinDir 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
|
||||
cliBinaryWrapperSrc string
|
||||
|
||||
depends []string
|
||||
}
|
||||
|
||||
func createDebPackages() {
|
||||
debPkgArch := pkgArch
|
||||
if pkgArch == "armv7" || pkgArch == "armv6" {
|
||||
debPkgArch = "armhf"
|
||||
}
|
||||
|
||||
createPackage(linuxPackageOptions{
|
||||
packageType: "deb",
|
||||
packageArch: debPkgArch,
|
||||
homeDir: "/usr/share/grafana",
|
||||
homeBinDir: "/usr/share/grafana/bin",
|
||||
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",
|
||||
cliBinaryWrapperSrc: "packaging/wrappers/grafana-cli",
|
||||
|
||||
depends: []string{"adduser", "libfontconfig1"},
|
||||
})
|
||||
}
|
||||
|
||||
func createRpmPackages() {
|
||||
rpmPkgArch := pkgArch
|
||||
switch {
|
||||
case pkgArch == "armv7":
|
||||
rpmPkgArch = "armhfp"
|
||||
case pkgArch == "arm64":
|
||||
rpmPkgArch = "aarch64"
|
||||
}
|
||||
createPackage(linuxPackageOptions{
|
||||
packageType: "rpm",
|
||||
packageArch: rpmPkgArch,
|
||||
homeDir: "/usr/share/grafana",
|
||||
homeBinDir: "/usr/share/grafana/bin",
|
||||
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",
|
||||
cliBinaryWrapperSrc: "packaging/wrappers/grafana-cli",
|
||||
|
||||
depends: []string{"/sbin/service", "fontconfig", "freetype", "urw-fonts"},
|
||||
})
|
||||
}
|
||||
|
||||
func createLinuxPackages() {
|
||||
if !skipDebGen {
|
||||
createDebPackages()
|
||||
}
|
||||
|
||||
if !skipRpmGen {
|
||||
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 grafana-cli wrapper
|
||||
runPrint("cp", "-p", options.cliBinaryWrapperSrc, filepath.Join(packageRoot, "/usr/sbin/"+cliBinary))
|
||||
|
||||
// copy grafana-server binary
|
||||
runPrint("cp", "-p", filepath.Join(workingDir, "tmp/bin/"+serverBinary), filepath.Join(packageRoot, "/usr/sbin/"+serverBinary))
|
||||
|
||||
// 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"))
|
||||
|
||||
// create /bin within home
|
||||
runPrint("mkdir", "-p", filepath.Join(packageRoot, options.homeBinDir))
|
||||
// The grafana-cli binary is exposed through a wrapper to ensure a proper
|
||||
// configuration is in place. To enable that, we need to store the original
|
||||
// binary in a separate location to avoid conflicts.
|
||||
runPrint("cp", "-p", filepath.Join(workingDir, "tmp/bin/"+cliBinary), filepath.Join(packageRoot, options.homeBinDir, cliBinary))
|
||||
|
||||
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")
|
||||
}
|
||||
fmt.Printf("pkgArch is set to '%s', generated arch is '%s'\n", pkgArch, options.packageArch)
|
||||
if pkgArch == "armv6" {
|
||||
name += "-rpi"
|
||||
args = append(args, "--replaces", "grafana")
|
||||
}
|
||||
args = append(args, "--name", name)
|
||||
|
||||
description := "Grafana"
|
||||
if enterprise {
|
||||
description += " Enterprise"
|
||||
}
|
||||
|
||||
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 options.packageArch != "" {
|
||||
args = append(args, "-a", options.packageArch)
|
||||
}
|
||||
|
||||
if linuxPackageIteration != "" {
|
||||
args = append(args, "--iteration", linuxPackageIteration)
|
||||
}
|
||||
|
||||
// add dependencies
|
||||
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 grunt(params ...string) {
|
||||
if runtime.GOOS == windows {
|
||||
runPrint(`.\node_modules\.bin\grunt`, params...)
|
||||
} else {
|
||||
runPrint("./node_modules/.bin/grunt", params...)
|
||||
}
|
||||
}
|
||||
|
||||
func genPackageVersion() string {
|
||||
if includeBuildId {
|
||||
return fmt.Sprintf("%v-%v", linuxPackageVersion, linuxPackageIteration)
|
||||
} else {
|
||||
return version
|
||||
}
|
||||
}
|
||||
|
||||
func gruntBuildArg(task string) []string {
|
||||
args := []string{task}
|
||||
args = append(args, fmt.Sprintf("--pkgVer=%v", genPackageVersion()))
|
||||
if pkgArch != "" {
|
||||
args = append(args, fmt.Sprintf("--arch=%v", pkgArch))
|
||||
}
|
||||
if libc != "" {
|
||||
args = append(args, fmt.Sprintf("--libc=%s", libc))
|
||||
}
|
||||
if enterprise {
|
||||
args = append(args, "--enterprise")
|
||||
}
|
||||
|
||||
args = append(args, fmt.Sprintf("--platform=%v", goos))
|
||||
|
||||
return args
|
||||
}
|
||||
|
||||
func setup() {
|
||||
runPrint("go", "install", "-v", "./pkg/cmd/grafana-server")
|
||||
}
|
||||
|
||||
func printGeneratedVersion() {
|
||||
fmt.Print(genPackageVersion())
|
||||
}
|
||||
|
||||
func test(pkg string) {
|
||||
setBuildEnv()
|
||||
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)
|
||||
if isDev {
|
||||
//don't include os/arch/libc in output path in dev environment
|
||||
binary = fmt.Sprintf("./bin/%s", binaryName)
|
||||
}
|
||||
|
||||
if goos == windows {
|
||||
binary += ".exe"
|
||||
}
|
||||
|
||||
if !isDev {
|
||||
rmr(binary, binary+".md5")
|
||||
}
|
||||
args := []string{"build", "-ldflags", ldflags()}
|
||||
if len(tags) > 0 {
|
||||
args = append(args, "-tags", strings.Join(tags, ","))
|
||||
}
|
||||
if race {
|
||||
args = append(args, "-race")
|
||||
}
|
||||
|
||||
args = append(args, "-o", binary)
|
||||
args = append(args, pkg)
|
||||
|
||||
if !isDev {
|
||||
setBuildEnv()
|
||||
runPrint("go", "version")
|
||||
libcPart := ""
|
||||
if libc != "" {
|
||||
libcPart = fmt.Sprintf("/%s", libc)
|
||||
}
|
||||
fmt.Printf("Targeting %s/%s%s\n", goos, goarch, libcPart)
|
||||
}
|
||||
|
||||
runPrint("go", args...)
|
||||
|
||||
if !isDev {
|
||||
// Create an md5 checksum of the binary, to be included in the archive for
|
||||
// automatic upgrades.
|
||||
err := md5File(binary)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ldflags() string {
|
||||
var b bytes.Buffer
|
||||
b.WriteString("-w")
|
||||
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()
|
||||
}
|
||||
|
||||
func rmr(paths ...string) {
|
||||
for _, path := range paths {
|
||||
log.Println("rm -r", path)
|
||||
os.RemoveAll(path)
|
||||
}
|
||||
}
|
||||
|
||||
func clean() {
|
||||
if isDev {
|
||||
return
|
||||
}
|
||||
|
||||
rmr("dist")
|
||||
rmr("tmp")
|
||||
rmr(filepath.Join(build.Default.GOPATH, fmt.Sprintf("pkg/%s_%s/github.com/grafana", goos, goarch)))
|
||||
}
|
||||
|
||||
func setBuildEnv() {
|
||||
os.Setenv("GOOS", goos)
|
||||
if goos == windows {
|
||||
// require windows >=7
|
||||
os.Setenv("CGO_CFLAGS", "-D_WIN32_WINNT=0x0601")
|
||||
}
|
||||
if goarch != "amd64" || goos != linux {
|
||||
// needed for all other archs
|
||||
cgo = true
|
||||
}
|
||||
if strings.HasPrefix(goarch, "armv") {
|
||||
os.Setenv("GOARCH", "arm")
|
||||
os.Setenv("GOARM", goarch[4:])
|
||||
} else {
|
||||
os.Setenv("GOARCH", goarch)
|
||||
}
|
||||
if goarch == "386" {
|
||||
os.Setenv("GO386", "387")
|
||||
}
|
||||
if cgo {
|
||||
os.Setenv("CGO_ENABLED", "1")
|
||||
}
|
||||
if gocc != "" {
|
||||
os.Setenv("CC", gocc)
|
||||
}
|
||||
}
|
||||
|
||||
func getGitBranch() string {
|
||||
v, err := runError("git", "rev-parse", "--abbrev-ref", "HEAD")
|
||||
if err != nil {
|
||||
return "master"
|
||||
}
|
||||
return string(v)
|
||||
}
|
||||
|
||||
func getGitSha() string {
|
||||
v, err := runError("git", "rev-parse", "--short", "HEAD")
|
||||
if err != nil {
|
||||
return "unknown-dev"
|
||||
}
|
||||
return string(v)
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
s, _ := strconv.ParseInt(string(bs), 10, 64)
|
||||
return s
|
||||
}
|
||||
|
||||
func runError(cmd string, args ...string) ([]byte, error) {
|
||||
ecmd := exec.Command(cmd, args...)
|
||||
bs, err := ecmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bytes.TrimSpace(bs), nil
|
||||
}
|
||||
|
||||
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()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func md5File(file string) error {
|
||||
fd, err := os.Open(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fd.Close()
|
||||
|
||||
h := md5.New()
|
||||
_, err = io.Copy(h, fd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out, err := os.Create(file + ".md5")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = fmt.Fprintf(out, "%x\n", h.Sum(nil))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return out.Close()
|
||||
}
|
||||
|
||||
func shaFilesInDist() {
|
||||
filepath.Walk("./dist", func(path string, f os.FileInfo, err error) error {
|
||||
if path == "./dist" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !strings.Contains(path, ".sha256") {
|
||||
err := shaFile(path)
|
||||
if err != nil {
|
||||
log.Printf("Failed to create sha file. error: %v\n", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func shaFile(file string) error {
|
||||
fd, err := os.Open(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fd.Close()
|
||||
|
||||
h := sha256.New()
|
||||
_, err = io.Copy(h, fd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out, err := os.Create(file + ".sha256")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = fmt.Fprintf(out, "%x\n", h.Sum(nil))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return out.Close()
|
||||
}
|
||||
|
||||
func shortenBuildId(buildId string) string {
|
||||
buildId = strings.Replace(buildId, "-", "", -1)
|
||||
if len(buildId) < 9 {
|
||||
return buildId
|
||||
}
|
||||
return buildId[0:8]
|
||||
}
|
||||
|
||||
@@ -66,13 +66,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 +98,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 =
|
||||
@@ -139,13 +126,10 @@ 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.
|
||||
# How long the data proxy waits 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
|
||||
|
||||
@@ -158,11 +142,6 @@ tls_handshake_timeout_seconds = 10
|
||||
# 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
|
||||
|
||||
@@ -172,12 +151,6 @@ 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
|
||||
|
||||
# Limit the amount of bytes that will be read/accepted from responses of outgoing HTTP requests.
|
||||
response_limit = 0
|
||||
|
||||
# Limits the number of rows that Grafana will process from SQL data sources.
|
||||
row_limit = 1000000
|
||||
|
||||
#################################### Analytics ###########################
|
||||
[analytics]
|
||||
# Server reporting, sends usage counters to stats.grafana.org every 24 hours.
|
||||
@@ -186,9 +159,6 @@ row_limit = 1000000
|
||||
# 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
|
||||
@@ -202,18 +172,6 @@ google_analytics_ua_id =
|
||||
# Google Tag Manager ID, only enabled if you specify an id here
|
||||
google_tag_manager_id =
|
||||
|
||||
# Rudderstack write key, enabled only if rudderstack_data_plane_url is also set
|
||||
rudderstack_write_key =
|
||||
|
||||
# Rudderstack data plane url, enabled only if rudderstack_write_key is also set
|
||||
rudderstack_data_plane_url =
|
||||
|
||||
# Application Insights connection string. Specify an URL string to enable this feature.
|
||||
application_insights_connection_string =
|
||||
|
||||
# Optional. Specifies an Application Insights endpoint URL where the endpoint string is wrapped in backticks ``.
|
||||
application_insights_endpoint_url =
|
||||
|
||||
#################################### Security ############################
|
||||
[security]
|
||||
# disable creation of admin user on first start of grafana
|
||||
@@ -228,12 +186,6 @@ admin_password = admin
|
||||
# used for signing
|
||||
secret_key = SW2YcwTIb9zpOOhoPsMm
|
||||
|
||||
# current key provider used for envelope encryption, default to static value specified by secret_key
|
||||
encryption_provider = secretKey
|
||||
|
||||
# list of configured key providers, space separated (Enterprise only): e.g., awskms.v1 azurekv.v1
|
||||
available_encryption_providers =
|
||||
|
||||
# disable gravatar profile images
|
||||
disable_gravatar = false
|
||||
|
||||
@@ -275,14 +227,6 @@ x_content_type_options = true
|
||||
# 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]
|
||||
@@ -311,11 +255,6 @@ 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
|
||||
@@ -343,9 +282,6 @@ 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 =
|
||||
@@ -360,9 +296,6 @@ 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
|
||||
@@ -379,7 +312,7 @@ 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
|
||||
@@ -497,7 +430,6 @@ 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]
|
||||
@@ -507,20 +439,14 @@ allow_sign_up = true
|
||||
client_id = some_id
|
||||
client_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
|
||||
groups_attribute_path =
|
||||
id_token_attribute_name =
|
||||
team_ids_attribute_path =
|
||||
auth_url =
|
||||
token_url =
|
||||
api_url =
|
||||
teams_url =
|
||||
allowed_domains =
|
||||
team_ids =
|
||||
allowed_organizations =
|
||||
@@ -528,7 +454,6 @@ tls_skip_verify_insecure = false
|
||||
tls_client_cert =
|
||||
tls_client_key =
|
||||
tls_client_ca =
|
||||
use_pkce = false
|
||||
|
||||
#################################### Basic Auth ##########################
|
||||
[auth.basic]
|
||||
@@ -547,58 +472,17 @@ 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]
|
||||
enabled = false
|
||||
config_file = /etc/grafana/ldap.toml
|
||||
allow_sign_up = true
|
||||
|
||||
# LDAP background sync (Enterprise only)
|
||||
# LDAP backround 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
|
||||
@@ -616,8 +500,7 @@ startTLS_policy =
|
||||
|
||||
[emails]
|
||||
welcome_email_on_sign_up = false
|
||||
templates_pattern = emails/*.html, emails/*.txt
|
||||
content_types = text/html
|
||||
templates_pattern = emails/*.html
|
||||
|
||||
#################################### Logging ##########################
|
||||
[log]
|
||||
@@ -676,25 +559,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
|
||||
@@ -712,9 +576,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
|
||||
|
||||
@@ -733,70 +594,11 @@ global_api_key = -1
|
||||
# global limit on number of logged in users.
|
||||
global_session = -1
|
||||
|
||||
# global limit of alerts
|
||||
global_alert_rule = -1
|
||||
|
||||
#################################### Unified Alerting ####################
|
||||
[unified_alerting]
|
||||
# Enable the Unified Alerting sub-system and interface. When enabled we'll migrate all of your alert rules and notification channels to the new system. New alert rules will be created and your notification channels will be converted into an Alertmanager configuration. Previous data is preserved to enable backwards compatibility but new data is removed when switching. When this configuration section and flag are not defined, the state is defined at runtime. See the documentation for more details.
|
||||
enabled =
|
||||
|
||||
# Comma-separated list of organization IDs for which to disable unified alerting. Only supported if unified alerting is enabled.
|
||||
disabled_orgs =
|
||||
|
||||
# Specify the frequency of polling for admin config changes.
|
||||
# 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.
|
||||
admin_config_poll_interval = 60s
|
||||
|
||||
# Specify the frequency of polling for Alertmanager config changes.
|
||||
# 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.
|
||||
alertmanager_config_poll_interval = 60s
|
||||
|
||||
# Listen address/hostname and port to receive unified alerting messages for other Grafana instances. The port is used for both TCP and UDP. It is assumed other Grafana instances are also running on the same port.
|
||||
ha_listen_address = "0.0.0.0:9094"
|
||||
|
||||
# Explicit address/hostname and port to advertise other Grafana instances. The port is used for both TCP and UDP.
|
||||
ha_advertise_address = ""
|
||||
|
||||
# Comma-separated list of initial instances (in a format of host:port) that will form the HA cluster. Configuring this setting will enable High Availability mode for alerting.
|
||||
ha_peers = ""
|
||||
|
||||
# Time to wait for an instance to send a notification via the Alertmanager. In HA, each Grafana instance will
|
||||
# be assigned a position (e.g. 0, 1). We then multiply this position with the timeout to indicate how long should
|
||||
# each instance wait before sending the notification to take into account replication lag.
|
||||
# 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.
|
||||
ha_peer_timeout = 15s
|
||||
|
||||
# The interval between sending gossip messages. By lowering this value (more frequent) gossip messages are propagated
|
||||
# across cluster more quickly at the expense of increased bandwidth usage.
|
||||
# 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.
|
||||
ha_gossip_interval = 200ms
|
||||
|
||||
# The interval between gossip full state syncs. Setting this interval lower (more frequent) will increase convergence speeds
|
||||
# across larger clusters at the expense of increased bandwidth usage.
|
||||
# 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.
|
||||
ha_push_pull_interval = 60s
|
||||
|
||||
# Enable or disable alerting rule execution. The alerting UI remains visible. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
execute_alerts = true
|
||||
|
||||
# Alert evaluation timeout when fetching data from the datasource. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
# The timeout string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
|
||||
evaluation_timeout = 30s
|
||||
|
||||
# Number of times we'll attempt to evaluate an alert rule before giving up on that evaluation. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
max_attempts = 3
|
||||
|
||||
# Minimum interval to enforce between rule evaluations. Rules will be adjusted if they are less than this value or if they are not multiple of the scheduler interval (10s). Higher values can help with resource management as we'll schedule fewer evaluations over time. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
# 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_interval = 10s
|
||||
|
||||
#################################### Alerting ############################
|
||||
[alerting]
|
||||
# Enable the legacy alerting sub-system and interface. If Unified Alerting is already enabled and you try to go back to legacy alerting, all data that is part of Unified Alerting will be deleted. When this configuration section and flag are not defined, the state is defined at runtime. See the documentation for more details.
|
||||
enabled =
|
||||
|
||||
# Makes it possible to turn off alert execution but alerting UI is visible
|
||||
# Disable alerting engine & UI features
|
||||
enabled = true
|
||||
# Makes it possible to turn off alert rule execution but alerting UI is visible
|
||||
execute_alerts = true
|
||||
|
||||
# Default setting for new alert rules. Defaults to categorize error and timeouts as alerting. (alerting, keep_state)
|
||||
@@ -829,9 +631,6 @@ max_annotation_age =
|
||||
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.
|
||||
@@ -871,12 +670,6 @@ disable_total_stats = false
|
||||
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 Grafana metrics to graphite
|
||||
[metrics.graphite]
|
||||
# Enable by setting the address setting (ex localhost:2003)
|
||||
@@ -906,8 +699,6 @@ 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.
|
||||
@@ -969,36 +760,8 @@ 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.
|
||||
# Enter a comma-separated list of plugin identifiers to identify plugins that are allowed to be loaded even if they lack a valid signature.
|
||||
allow_loading_unsigned_plugins =
|
||||
# Enable or disable installing / uninstalling / updating plugins directly from within Grafana.
|
||||
plugin_admin_enabled = true
|
||||
plugin_admin_external_manage_enabled = false
|
||||
plugin_catalog_url = https://grafana.com/grafana/plugins/
|
||||
# Enter a comma-separated list of plugin identifiers to hide in the plugin catalog.
|
||||
plugin_catalog_hidden_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 =
|
||||
|
||||
# engine defines an HA (high availability) engine to use for Grafana Live. By default no engine used - in
|
||||
# this case Live features work only on a single Grafana server.
|
||||
# Available options: "redis".
|
||||
# Setting ha_engine is an EXPERIMENTAL feature.
|
||||
ha_engine =
|
||||
|
||||
# ha_engine_address sets a connection address for Live HA engine. Depending on engine type address format can differ.
|
||||
# For now we only support Redis connection address in "host:port" format.
|
||||
# This option is EXPERIMENTAL.
|
||||
ha_engine_address = "127.0.0.1:6379"
|
||||
|
||||
#################################### Grafana Image Renderer Plugin ##########################
|
||||
[plugin.grafana-image-renderer]
|
||||
@@ -1043,14 +806,12 @@ rendering_chrome_bin =
|
||||
# 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'
|
||||
# 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 the maximum number of browser instances/incognito pages that can execute concurrently. Default is '5'.
|
||||
# When rendering_mode = clustered you can define maximum number of browser instances/incognito pages that can execute concurrently..
|
||||
rendering_clustering_max_concurrency =
|
||||
# When rendering_mode = clustered, you can specify the duration a rendering request can take before it will time out. Default is `30` seconds.
|
||||
rendering_clustering_timeout =
|
||||
|
||||
# Limit the maximum viewport width, height and device scale factor that can be requested.
|
||||
rendering_viewport_max_width =
|
||||
@@ -1088,14 +849,3 @@ 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
|
||||
|
||||
[geomap]
|
||||
# Set the JSON configuration for the default basemap
|
||||
default_baselayer_config =
|
||||
|
||||
# Enable or disable loading other base map layers
|
||||
enable_custom_baselayers = 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
|
||||
|
||||
@@ -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
|
||||
262
conf/sample.ini
262
conf/sample.ini
@@ -67,13 +67,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,12 +87,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 =
|
||||
@@ -123,11 +110,6 @@
|
||||
# For "sqlite3" only. cache mode setting used for connecting to the database. (private, shared)
|
||||
;cache_mode = private
|
||||
|
||||
################################### 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
|
||||
|
||||
#################################### Cache server #############################
|
||||
[remote_cache]
|
||||
# Either "redis", "memcached" or "database" default is "database"
|
||||
@@ -145,13 +127,10 @@
|
||||
# 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.
|
||||
# How long the data proxy waits 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
|
||||
|
||||
@@ -164,11 +143,6 @@
|
||||
# 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
|
||||
|
||||
@@ -178,12 +152,6 @@
|
||||
# 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
|
||||
|
||||
# Limit the amount of bytes that will be read/accepted from responses of outgoing HTTP requests.
|
||||
;response_limit = 0
|
||||
|
||||
# Limits the number of rows that Grafana will process from SQL data sources.
|
||||
;row_limit = 1000000
|
||||
|
||||
#################################### Analytics ####################################
|
||||
[analytics]
|
||||
# Server reporting, sends usage counters to stats.grafana.org every 24 hours.
|
||||
@@ -192,9 +160,6 @@
|
||||
# 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
|
||||
# in some UI views to notify that grafana or plugin update exists
|
||||
@@ -222,12 +187,6 @@
|
||||
# used for signing
|
||||
;secret_key = SW2YcwTIb9zpOOhoPsMm
|
||||
|
||||
# current key provider used for envelope encryption, default to static value specified by secret_key
|
||||
;encryption_provider = secretKey
|
||||
|
||||
# list of configured key providers, space separated (Enterprise only): e.g., awskms.v1 azurekv.v1
|
||||
;available_encryption_providers =
|
||||
|
||||
# disable gravatar profile images
|
||||
;disable_gravatar = false
|
||||
|
||||
@@ -269,15 +228,6 @@
|
||||
# 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
|
||||
@@ -331,9 +281,6 @@
|
||||
# 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 =
|
||||
@@ -348,9 +295,6 @@
|
||||
# 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
|
||||
@@ -367,7 +311,7 @@
|
||||
# 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
|
||||
@@ -476,7 +420,6 @@
|
||||
;allowed_domains =
|
||||
;allowed_groups =
|
||||
;role_attribute_path =
|
||||
;role_attribute_strict = false
|
||||
|
||||
#################################### Generic OAuth ##########################
|
||||
[auth.generic_oauth]
|
||||
@@ -486,28 +429,21 @@
|
||||
;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
|
||||
;teams_url =
|
||||
;allowed_domains =
|
||||
;team_ids =
|
||||
;allowed_organizations =
|
||||
;role_attribute_path =
|
||||
;role_attribute_strict = false
|
||||
;groups_attribute_path =
|
||||
;team_ids_attribute_path =
|
||||
;tls_skip_verify_insecure = false
|
||||
;tls_client_cert =
|
||||
;tls_client_key =
|
||||
;tls_client_ca =
|
||||
;use_pkce = false
|
||||
|
||||
#################################### Basic Auth ##########################
|
||||
[auth.basic]
|
||||
@@ -525,55 +461,17 @@
|
||||
# Read the auth proxy docs for details on what the setting below enables
|
||||
;enable_login_token = false
|
||||
|
||||
#################################### Auth JWT ##########################
|
||||
[auth.jwt]
|
||||
;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]
|
||||
;enabled = false
|
||||
;config_file = /etc/grafana/ldap.toml
|
||||
;allow_sign_up = true
|
||||
|
||||
# LDAP background sync (Enterprise only)
|
||||
# LDAP backround 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
|
||||
@@ -593,8 +491,7 @@
|
||||
|
||||
[emails]
|
||||
;welcome_email_on_sign_up = false
|
||||
;templates_pattern = emails/*.html, emails/*.txt
|
||||
;content_types = text/html
|
||||
;templates_pattern = emails/*.html
|
||||
|
||||
#################################### Logging ##########################
|
||||
[log]
|
||||
@@ -653,25 +550,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
|
||||
@@ -689,9 +567,6 @@
|
||||
# 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
|
||||
|
||||
@@ -710,70 +585,11 @@
|
||||
# global limit on number of logged in users.
|
||||
; global_session = -1
|
||||
|
||||
# global limit of alerts
|
||||
;global_alert_rule = -1
|
||||
|
||||
#################################### Unified Alerting ####################
|
||||
[unified_alerting]
|
||||
#Enable the Unified Alerting sub-system and interface. When enabled we'll migrate all of your alert rules and notification channels to the new system. New alert rules will be created and your notification channels will be converted into an Alertmanager configuration. Previous data is preserved to enable backwards compatibility but new data is removed.```
|
||||
;enabled = true
|
||||
|
||||
# Comma-separated list of organization IDs for which to disable unified alerting. Only supported if unified alerting is enabled.
|
||||
;disabled_orgs =
|
||||
|
||||
# Specify the frequency of polling for admin config changes.
|
||||
# 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.
|
||||
;admin_config_poll_interval = 60s
|
||||
|
||||
# Specify the frequency of polling for Alertmanager config changes.
|
||||
# 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.
|
||||
;alertmanager_config_poll_interval = 60s
|
||||
|
||||
# Listen address/hostname and port to receive unified alerting messages for other Grafana instances. The port is used for both TCP and UDP. It is assumed other Grafana instances are also running on the same port. The default value is `0.0.0.0:9094`.
|
||||
;ha_listen_address = "0.0.0.0:9094"
|
||||
|
||||
# Listen address/hostname and port to receive unified alerting messages for other Grafana instances. The port is used for both TCP and UDP. It is assumed other Grafana instances are also running on the same port. The default value is `0.0.0.0:9094`.
|
||||
;ha_advertise_address = ""
|
||||
|
||||
# Comma-separated list of initial instances (in a format of host:port) that will form the HA cluster. Configuring this setting will enable High Availability mode for alerting.
|
||||
;ha_peers = ""
|
||||
|
||||
# Time to wait for an instance to send a notification via the Alertmanager. In HA, each Grafana instance will
|
||||
# be assigned a position (e.g. 0, 1). We then multiply this position with the timeout to indicate how long should
|
||||
# each instance wait before sending the notification to take into account replication lag.
|
||||
# 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.
|
||||
;ha_peer_timeout = "15s"
|
||||
|
||||
# The interval between sending gossip messages. By lowering this value (more frequent) gossip messages are propagated
|
||||
# across cluster more quickly at the expense of increased bandwidth usage.
|
||||
# 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.
|
||||
;ha_gossip_interval = "200ms"
|
||||
|
||||
# The interval between gossip full state syncs. Setting this interval lower (more frequent) will increase convergence speeds
|
||||
# across larger clusters at the expense of increased bandwidth usage.
|
||||
# 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.
|
||||
;ha_push_pull_interval = "60s"
|
||||
|
||||
# Enable or disable alerting rule execution. The alerting UI remains visible. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
;execute_alerts = true
|
||||
|
||||
# Alert evaluation timeout when fetching data from the datasource. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
# The timeout string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
|
||||
;evaluation_timeout = 30s
|
||||
|
||||
# Number of times we'll attempt to evaluate an alert rule before giving up on that evaluation. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
;max_attempts = 3
|
||||
|
||||
# Minimum interval to enforce between rule evaluations. Rules will be adjusted if they are less than this value or if they are not multiple of the scheduler interval (10s). Higher values can help with resource management as we'll schedule fewer evaluations over time. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
# 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_interval = 10s
|
||||
|
||||
#################################### Alerting ############################
|
||||
[alerting]
|
||||
# Disable legacy alerting engine & UI features
|
||||
;enabled = false
|
||||
|
||||
# Makes it possible to turn off alert execution but alerting UI is visible
|
||||
# Disable alerting engine & UI features
|
||||
;enabled = true
|
||||
# Makes it possible to turn off alert rule execution but alerting UI is visible
|
||||
;execute_alerts = true
|
||||
|
||||
# Default setting for new alert rules. Defaults to categorize error and timeouts as alerting. (alerting, keep_state)
|
||||
@@ -786,6 +602,7 @@
|
||||
# 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
|
||||
|
||||
@@ -806,9 +623,6 @@
|
||||
;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.
|
||||
@@ -850,12 +664,6 @@
|
||||
; 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]
|
||||
# Enable by setting the address setting (ex localhost:2003)
|
||||
@@ -883,8 +691,6 @@
|
||||
# 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.
|
||||
@@ -942,35 +748,8 @@
|
||||
[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.
|
||||
# Enter a comma-separated list of plugin identifiers to identify plugins that are allowed to be loaded even if they lack a valid signature.
|
||||
;allow_loading_unsigned_plugins =
|
||||
# Enable or disable installing / uninstalling / updating plugins directly from within Grafana.
|
||||
;plugin_admin_enabled = false
|
||||
;plugin_admin_external_manage_enabled = false
|
||||
;plugin_catalog_url = https://grafana.com/grafana/plugins/
|
||||
# Enter a comma-separated list of plugin identifiers to hide in the plugin catalog.
|
||||
;plugin_catalog_hidden_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 =
|
||||
|
||||
# engine defines an HA (high availability) engine to use for Grafana Live. By default no engine used - in
|
||||
# this case Live features work only on a single Grafana server. Available options: "redis".
|
||||
# Setting ha_engine is an EXPERIMENTAL feature.
|
||||
;ha_engine =
|
||||
|
||||
# ha_engine_address sets a connection address for Live HA engine. Depending on engine type address format can differ.
|
||||
# For now we only support Redis connection address in "host:port" format.
|
||||
# This option is EXPERIMENTAL.
|
||||
;ha_engine_address = "127.0.0.1:6379"
|
||||
|
||||
#################################### Grafana Image Renderer Plugin ##########################
|
||||
[plugin.grafana-image-renderer]
|
||||
@@ -1015,14 +794,12 @@
|
||||
# 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'
|
||||
# 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 the maximum number of browser instances/incognito pages that can execute concurrently. Default is '5'.
|
||||
# When rendering_mode = clustered you can define maximum number of browser instances/incognito pages that can execute concurrently..
|
||||
;rendering_clustering_max_concurrency =
|
||||
# When rendering_mode = clustered, you can specify the duration a rendering request can take before it will time out. Default is `30` seconds.
|
||||
;rendering_clustering_timeout =
|
||||
|
||||
# Limit the maximum viewport width, height and device scale factor that can be requested.
|
||||
;rendering_viewport_max_width =
|
||||
@@ -1061,20 +838,3 @@
|
||||
|
||||
# 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
|
||||
|
||||
[geomap]
|
||||
# Set the JSON configuration for the default basemap
|
||||
;default_baselayer_config = `{
|
||||
; "type": "xyz",
|
||||
; "config": {
|
||||
; "attribution": "Open street map",
|
||||
; "url": "https://tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||
; }
|
||||
;}`
|
||||
|
||||
# Enable or disable loading other base map layers
|
||||
;enable_custom_baselayers = true
|
||||
|
||||
@@ -6,7 +6,6 @@ This directory contains guides for contributors to the Grafana project.
|
||||
- [Contributing documentation](documentation.md)
|
||||
- [Developer guide](developer-guide.md)
|
||||
- [Triage issues](triage-issues.md)
|
||||
- [Merge a pull request](merge-pull-request.md)
|
||||
|
||||
The `style-guides` directory contains style guides for the Grafana software project and documentation.
|
||||
|
||||
|
||||
@@ -4,10 +4,7 @@ Are you looking to take on contributions with bigger impact? These guides help y
|
||||
|
||||
Learn more about the backend architecture:
|
||||
|
||||
- Part 1: [Services](backend/services.md)
|
||||
- Part 2: [Communication](backend/communication.md)
|
||||
- Part 3: [Database](backend/database.md)
|
||||
- Part 1: [Services](services.md)
|
||||
- Part 2: [Communication](communication.md)
|
||||
- Part 3: [Database](database.md)
|
||||
|
||||
Learn more about the frontend architecture:
|
||||
|
||||
- Part 1: [Data requests](frontend-data-requests.md)
|
||||
|
||||
@@ -1,133 +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 `context.Context` and object to the `DispatchCtx` method:
|
||||
|
||||
```go
|
||||
// context.Context from caller
|
||||
ctx := req.Request.Context()
|
||||
cmd := &models.SendStickersCommand {
|
||||
UserID: "taylor",
|
||||
Count: 1,
|
||||
}
|
||||
if err := s.bus.DispatchCtx(ctx, cmd); err != nil {
|
||||
if err == bus.ErrHandlerNotFound {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
```
|
||||
|
||||
> **Note:** `DispatchCtx` will return an error if no handler is registered for that command.
|
||||
|
||||
> **Note:** `Dispatch` currently exists and requires no `context.Context` to be provided, but it's strongly suggested to not use this since there's an ongoing refactoring to remove usage of non-context-aware functions/methods and use context.Context everywhere.
|
||||
|
||||
**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.AddHandlerCtx(s.SendStickers)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MyService) SendStickers(ctx context.Context, cmd *models.SendStickersCommand) error {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
> **Note:** The handler method may return an error if unable to complete the command.
|
||||
|
||||
> **Note:** `AddHandler` currently exists and requires no `context.Context` to be provided, but it's strongly suggested to not use this since there's an ongoing refactoring to remove usage of non-context-aware functions/methods and use context.Context everywhere.
|
||||
|
||||
## 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 `DispatchCtx` method returns, the `Results` field contains the result of the query.
|
||||
|
||||
```go
|
||||
// context.Context from caller
|
||||
ctx := req.Request.Context()
|
||||
query := &models.FindDashboardQuery{
|
||||
ID: "foo",
|
||||
}
|
||||
if err := bus.DispatchCtx(ctx, query); err != nil {
|
||||
return err
|
||||
}
|
||||
// The query now contains a result.
|
||||
for _, item := range query.Results {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
> **Note:** `Dispatch` currently exists and requires no `context.Context` to be provided, but it's strongly suggested to not use this since there's an ongoing refactoring to remove usage of non-context-aware functions/methods and use context.Context everywhere.
|
||||
|
||||
### 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(ctx context.Context, query *models.FindDashboardQuery) error {
|
||||
// ...
|
||||
query.Result = dashboard
|
||||
return nil
|
||||
}
|
||||
```
|
||||
@@ -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.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user