mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2025-12-24 14:50:39 -05:00
Compare commits
5 Commits
4.0.0-rc.2
...
runTestInC
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e362f04093 | ||
|
|
9f01bf1af3 | ||
|
|
217a84b360 | ||
|
|
e40d7f4246 | ||
|
|
827a053ac0 |
@@ -886,12 +886,16 @@ def localApiTestPipeline(ctx):
|
||||
if ctx.build.event == "cron" or "full-ci" in ctx.build.title.lower():
|
||||
with_remote_php.append(False)
|
||||
|
||||
storages = ["decomposed"]
|
||||
if "posix" in ctx.build.title.lower():
|
||||
storages = ["posix"]
|
||||
|
||||
defaults = {
|
||||
"suites": {},
|
||||
"skip": False,
|
||||
"extraEnvironment": {},
|
||||
"extraServerEnvironment": {},
|
||||
"storages": ["decomposed"],
|
||||
"storages": storages,
|
||||
"accounts_hash_difficulty": 4,
|
||||
"emailNeeded": False,
|
||||
"antivirusNeeded": False,
|
||||
@@ -945,7 +949,7 @@ def localApiTestPipeline(ctx):
|
||||
|
||||
def localApiTests(ctx, name, suites, storage = "decomposed", extra_environment = {}, with_remote_php = False):
|
||||
test_dir = "%s/tests/acceptance" % dirs["base"]
|
||||
expected_failures_file = "%s/expected-failures-localAPI-on-%s-storage.md" % (test_dir, storage)
|
||||
expected_failures_file = "%s/expected-failures-localAPI-on-decomposed-storage.md" % (test_dir)
|
||||
|
||||
environment = {
|
||||
"TEST_SERVER_URL": OC_URL,
|
||||
@@ -1122,10 +1126,10 @@ def wopiValidatorTests(ctx, storage, wopiServerType, accounts_hash_difficulty =
|
||||
],
|
||||
}
|
||||
|
||||
def coreApiTests(ctx, part_number = 1, number_of_parts = 1, with_remote_php = False, storage = "ocis", accounts_hash_difficulty = 4):
|
||||
def coreApiTests(ctx, part_number = 1, number_of_parts = 1, with_remote_php = False, storage = "posix", accounts_hash_difficulty = 4):
|
||||
filterTags = "~@skipOnGraph&&~@skipOnOcis-%s-Storage" % ("OC" if storage == "owncloud" else "OCIS")
|
||||
test_dir = "%s/tests/acceptance" % dirs["base"]
|
||||
expected_failures_file = "%s/expected-failures-API-on-%s-storage.md" % (test_dir, storage.upper())
|
||||
expected_failures_file = "%s/expected-failures-API-on-decomposed-storage.md" % (test_dir)
|
||||
|
||||
return {
|
||||
"name": "Core-API-Tests-%s%s" % (part_number, "-withoutRemotePhp" if not with_remote_php else ""),
|
||||
@@ -1186,10 +1190,13 @@ def apiTests(ctx):
|
||||
"withRemotePhp": with_remote_php,
|
||||
}
|
||||
|
||||
if "posix" in ctx.build.title.lower():
|
||||
storage = "posix"
|
||||
|
||||
for runPart in range(1, config["apiTests"]["numberOfParts"] + 1):
|
||||
for run_with_remote_php in defaults["withRemotePhp"]:
|
||||
if (not debugPartsEnabled or (debugPartsEnabled and runPart in debugParts)):
|
||||
pipelines.append(coreApiTests(ctx, runPart, config["apiTests"]["numberOfParts"], run_with_remote_php))
|
||||
pipelines.append(coreApiTests(ctx, runPart, config["apiTests"]["numberOfParts"], run_with_remote_php, storage))
|
||||
|
||||
return pipelines
|
||||
|
||||
@@ -1337,6 +1344,10 @@ def multiServiceE2ePipeline(ctx):
|
||||
if (not "full-ci" in ctx.build.title.lower() and ctx.build.event != "cron"):
|
||||
return pipelines
|
||||
|
||||
storage = "decomposed"
|
||||
if "posix" in ctx.build.title.lower():
|
||||
storage = "posix"
|
||||
|
||||
extra_server_environment = {
|
||||
"OCIS_PASSWORD_POLICY_BANNED_PASSWORDS_LIST": "%s" % dirs["bannedPasswordList"],
|
||||
"OCIS_JWT_SECRET": "some-ocis-jwt-secret",
|
||||
@@ -1408,7 +1419,7 @@ def multiServiceE2ePipeline(ctx):
|
||||
restoreWebCache() + \
|
||||
restoreWebPnpmCache() + \
|
||||
tikaService() + \
|
||||
opencloudServer(extra_server_environment = extra_server_environment, tika_enabled = params["tikaNeeded"]) + \
|
||||
opencloudServer(storage, extra_server_environment = extra_server_environment, tika_enabled = params["tikaNeeded"]) + \
|
||||
storage_users_services + \
|
||||
[{
|
||||
"name": "e2e-tests",
|
||||
@@ -2009,6 +2020,7 @@ def opencloudServer(storage = "decomposed", accounts_hash_difficulty = 4, volume
|
||||
"OC_URL": OC_URL,
|
||||
"OC_CONFIG_DIR": "/root/.opencloud/config", # needed for checking config later
|
||||
"STORAGE_USERS_DRIVER": "%s" % (storage),
|
||||
"STORAGE_USERS_ID_CACHE_STORE": "nats-js-kv",
|
||||
"PROXY_ENABLE_BASIC_AUTH": True,
|
||||
"WEB_UI_CONFIG_FILE": "%s/%s" % (dirs["base"], dirs["opencloudConfig"]),
|
||||
"OC_LOG_LEVEL": "error",
|
||||
|
||||
10
go.mod
10
go.mod
@@ -21,7 +21,7 @@ require (
|
||||
github.com/egirna/icap-client v0.1.1
|
||||
github.com/gabriel-vasile/mimetype v1.4.8
|
||||
github.com/ggwhite/go-masker v1.1.0
|
||||
github.com/go-chi/chi/v5 v5.2.0
|
||||
github.com/go-chi/chi/v5 v5.2.1
|
||||
github.com/go-chi/render v1.0.3
|
||||
github.com/go-ldap/ldap/v3 v3.4.10
|
||||
github.com/go-ldap/ldif v0.0.0-20200320164324-fd88d9b715b3
|
||||
@@ -63,7 +63,7 @@ require (
|
||||
github.com/onsi/ginkgo/v2 v2.23.0
|
||||
github.com/onsi/gomega v1.36.2
|
||||
github.com/open-policy-agent/opa v1.1.0
|
||||
github.com/opencloud-eu/reva/v2 v2.27.3-0.20250312134906-766c69c5d1be
|
||||
github.com/opencloud-eu/reva/v2 v2.27.3-0.20250314084055-d2fcfe6b3445
|
||||
github.com/orcaman/concurrent-map v1.0.0
|
||||
github.com/owncloud/libre-graph-api-go v1.0.5-0.20240829135935-80dc00d6f5ea
|
||||
github.com/pkg/errors v0.9.1
|
||||
@@ -274,7 +274,7 @@ require (
|
||||
github.com/pjbgf/sha1cd v0.3.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/pquerna/cachecontrol v0.2.0 // indirect
|
||||
github.com/prometheus/alertmanager v0.27.0 // indirect
|
||||
github.com/prometheus/alertmanager v0.28.1 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.62.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
@@ -289,8 +289,8 @@ require (
|
||||
github.com/sercand/kuberesolver/v5 v5.1.1 // indirect
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
|
||||
github.com/sethvargo/go-password v0.3.1 // indirect
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect
|
||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 // indirect
|
||||
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c // indirect
|
||||
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92 // indirect
|
||||
github.com/skeema/knownhosts v1.3.0 // indirect
|
||||
github.com/spacewander/go-suffix-tree v0.0.0-20191010040751-0865e368c784 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
|
||||
23
go.sum
23
go.sum
@@ -133,9 +133,8 @@ github.com/bbalet/stopwords v1.0.0/go.mod h1:sAWrQoDMfqARGIn4s6dp7OW7ISrshUD8IP2
|
||||
github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
|
||||
github.com/beevik/etree v1.5.0 h1:iaQZFSDS+3kYZiGoc9uKeOkUY3nYMXOKLl6KIJxiJWs=
|
||||
github.com/beevik/etree v1.5.0/go.mod h1:gPNJNaBGVZ9AwsidazFZyygnd+0pAU38N4D+WemwKNs=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
|
||||
github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
@@ -338,8 +337,8 @@ github.com/go-asn1-ber/asn1-ber v1.4.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkPro
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.7 h1:DTX+lbVTWaTw1hQ+PbZPlnDZPEIs0SS/GCZAl535dDk=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.7/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
|
||||
github.com/go-chi/chi/v5 v5.2.0 h1:Aj1EtB0qR2Rdo2dG4O94RIU35w2lvQSj6BRA4+qwFL0=
|
||||
github.com/go-chi/chi/v5 v5.2.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8=
|
||||
github.com/go-chi/chi/v5 v5.2.1/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
|
||||
github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4=
|
||||
github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0=
|
||||
github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s=
|
||||
@@ -865,8 +864,8 @@ github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
|
||||
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
|
||||
github.com/open-policy-agent/opa v1.1.0 h1:HMz2evdEMTyNqtdLjmu3Vyx06BmhNYAx67Yz3Ll9q2s=
|
||||
github.com/open-policy-agent/opa v1.1.0/go.mod h1:T1pASQ1/vwfTa+e2fYcfpLCvWgYtqtiUv+IuA/dLPQs=
|
||||
github.com/opencloud-eu/reva/v2 v2.27.3-0.20250312134906-766c69c5d1be h1:dxKsVUzdKIGf1hfGdr1GH6NFfo0xuIcPma/qjHNG8mU=
|
||||
github.com/opencloud-eu/reva/v2 v2.27.3-0.20250312134906-766c69c5d1be/go.mod h1:sqlExPoEnEd0KdfoSKogV8PrwEBY3l06icoa4gJnGnU=
|
||||
github.com/opencloud-eu/reva/v2 v2.27.3-0.20250314084055-d2fcfe6b3445 h1:At2GtwEeNls1P60RpBa9QQridCtFQNW/pnQ5tybT8X0=
|
||||
github.com/opencloud-eu/reva/v2 v2.27.3-0.20250314084055-d2fcfe6b3445/go.mod h1:yCscyJJ7FX/HA2fexM2i1OyKSZnJgdq1vnoXgXKmnn8=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||
@@ -911,8 +910,8 @@ github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndr
|
||||
github.com/pquerna/cachecontrol v0.2.0 h1:vBXSNuE5MYP9IJ5kjsdo8uq+w41jSPgvba2DEnkRx9k=
|
||||
github.com/pquerna/cachecontrol v0.2.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
|
||||
github.com/pquerna/otp v1.3.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
||||
github.com/prometheus/alertmanager v0.27.0 h1:V6nTa2J5V4s8TG4C4HtrBP/WNSebCCTYGGv4qecA/+I=
|
||||
github.com/prometheus/alertmanager v0.27.0/go.mod h1:8Ia/R3urPmbzJ8OsdvmZvIprDwvwmYCmUbwBL+jlPOE=
|
||||
github.com/prometheus/alertmanager v0.28.1 h1:BK5pCoAtaKg01BYRUJhEDV1tqJMEtYBGzPw8QdvnnvA=
|
||||
github.com/prometheus/alertmanager v0.28.1/go.mod h1:0StpPUDDHi1VXeM7p2yYfeZgLVi/PPlt39vo9LQUHxM=
|
||||
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
@@ -1010,11 +1009,11 @@ github.com/shamaton/msgpack/v2 v2.2.2 h1:GOIg0c9LV04VwzOOqZSrmsv/JzjNOOMxnS/HvOH
|
||||
github.com/shamaton/msgpack/v2 v2.2.2/go.mod h1:6khjYnkx73f7VQU7wjcFS9DFjs+59naVWJv1TB7qdOI=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c h1:aqg5Vm5dwtvL+YgDpBcK1ITf3o96N/K7/wsRXQnUTEs=
|
||||
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c/go.mod h1:owqhoLW1qZoYLZzLnBw+QkPP9WZnjlSWihhxAJC1+/M=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 h1:pXY9qYc/MP5zdvqWEUH6SjNiu7VhSjuVFTFiTcphaLU=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92 h1:OfRzdxCzDhp+rsKWXuOO2I/quKMJ/+TQwVbIP/gltZg=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92/go.mod h1:7/OT02F6S6I7v6WXb+IjhMuZEYfH/RJ5RwEWnEo5BMg=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
|
||||
32
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/trashbin/trashbin.go
generated
vendored
32
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/trashbin/trashbin.go
generated
vendored
@@ -26,13 +26,13 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/rs/zerolog"
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/errtypes"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/lookup"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/options"
|
||||
@@ -145,7 +145,7 @@ func trashRootForNode(n *node.Node) string {
|
||||
}
|
||||
|
||||
func (tb *Trashbin) MoveToTrash(ctx context.Context, n *node.Node, path string) error {
|
||||
key := uuid.New().String()
|
||||
key := n.ID
|
||||
trashPath := trashRootForNode(n)
|
||||
|
||||
err := os.MkdirAll(filepath.Join(trashPath, "info"), 0755)
|
||||
@@ -197,6 +197,30 @@ func (tb *Trashbin) ListRecycle(ctx context.Context, spaceID string, key, relati
|
||||
return nil, err
|
||||
}
|
||||
originalPath = filepath.Join(originalPath, relativePath)
|
||||
|
||||
fi, err := os.Stat(base)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
item := &provider.RecycleItem{
|
||||
Key: filepath.Join(key, relativePath),
|
||||
Size: uint64(fi.Size()),
|
||||
Ref: &provider.Reference{
|
||||
ResourceId: &provider.ResourceId{
|
||||
SpaceId: spaceID,
|
||||
OpaqueId: spaceID,
|
||||
},
|
||||
Path: originalPath,
|
||||
},
|
||||
DeletionTime: ts,
|
||||
Type: provider.ResourceType_RESOURCE_TYPE_FILE,
|
||||
}
|
||||
if fi.IsDir() {
|
||||
item.Type = provider.ResourceType_RESOURCE_TYPE_CONTAINER
|
||||
} else {
|
||||
item.Type = provider.ResourceType_RESOURCE_TYPE_FILE
|
||||
}
|
||||
return []*provider.RecycleItem{item}, nil
|
||||
}
|
||||
|
||||
items := []*provider.RecycleItem{}
|
||||
@@ -287,6 +311,10 @@ func (tb *Trashbin) RestoreRecycleItem(ctx context.Context, spaceID string, key,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if id == "" {
|
||||
return nil, errtypes.NotFound("trashbin: item not found")
|
||||
|
||||
}
|
||||
|
||||
// update parent id in case it was restored to a different location
|
||||
_, parentID, _, err := tb.lu.MetadataBackend().IdentifyPath(ctx, filepath.Dir(restorePath))
|
||||
|
||||
9
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/decomposedfs.go
generated
vendored
9
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/decomposedfs.go
generated
vendored
@@ -102,6 +102,10 @@ type Session interface {
|
||||
LockID() string
|
||||
}
|
||||
|
||||
type IDCachingTree interface {
|
||||
WarmupIDCache(root string, assimilate, onlyDirty bool) error
|
||||
}
|
||||
|
||||
type SessionStore interface {
|
||||
New(ctx context.Context) *upload.DecomposedFsSession
|
||||
List(ctx context.Context) ([]*upload.DecomposedFsSession, error)
|
||||
@@ -1304,6 +1308,11 @@ func (fs *Decomposedfs) RestoreRecycleItem(ctx context.Context, space *provider.
|
||||
return err
|
||||
}
|
||||
sizeDiff = int64(treeSize)
|
||||
|
||||
// Warmup posix IDCache if restored path is a directory
|
||||
if cachingTree, ok := fs.tp.(IDCachingTree); ok {
|
||||
_ = cachingTree.WarmupIDCache(restoredNode.InternalPath(), false, false)
|
||||
}
|
||||
} else {
|
||||
sizeDiff = restoredNode.Blobsize
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ func New(m map[string]interface{}) (*Options, error) {
|
||||
o.Root = filepath.Clean(o.Root)
|
||||
|
||||
if o.PersonalSpaceAliasTemplate == "" {
|
||||
o.PersonalSpaceAliasTemplate = "{{.SpaceType}}/{{.User.Username}}"
|
||||
o.PersonalSpaceAliasTemplate = "{{.SpaceType}}/{{.User.Username | lower}}"
|
||||
}
|
||||
|
||||
if o.GeneralSpaceAliasTemplate == "" {
|
||||
|
||||
5
vendor/github.com/prometheus/alertmanager/NOTICE
generated
vendored
5
vendor/github.com/prometheus/alertmanager/NOTICE
generated
vendored
@@ -11,8 +11,3 @@ Bootstrap
|
||||
http://getbootstrap.com
|
||||
Copyright 2011-2014 Twitter, Inc.
|
||||
Licensed under the MIT License
|
||||
|
||||
bootstrap-datetimepicker.js
|
||||
http://www.eyecon.ro/bootstrap-datepicker
|
||||
Copyright 2012 Stefan Petre
|
||||
Licensed under the Apache License, Version 2.0
|
||||
|
||||
12
vendor/github.com/prometheus/alertmanager/asset/assets_vfsdata.go
generated
vendored
12
vendor/github.com/prometheus/alertmanager/asset/assets_vfsdata.go
generated
vendored
File diff suppressed because one or more lines are too long
52
vendor/github.com/prometheus/alertmanager/featurecontrol/featurecontrol.go
generated
vendored
52
vendor/github.com/prometheus/alertmanager/featurecontrol/featurecontrol.go
generated
vendored
@@ -16,35 +16,41 @@ package featurecontrol
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
)
|
||||
|
||||
const (
|
||||
FeatureReceiverNameInMetrics = "receiver-name-in-metrics"
|
||||
FeatureClassicMode = "classic-mode"
|
||||
FeatureUTF8StrictMode = "utf8-strict-mode"
|
||||
FeatureAutoGOMEMLIMIT = "auto-gomemlimit"
|
||||
FeatureAutoGOMAXPROCS = "auto-gomaxprocs"
|
||||
)
|
||||
|
||||
var AllowedFlags = []string{
|
||||
FeatureReceiverNameInMetrics,
|
||||
FeatureClassicMode,
|
||||
FeatureUTF8StrictMode,
|
||||
FeatureAutoGOMEMLIMIT,
|
||||
FeatureAutoGOMAXPROCS,
|
||||
}
|
||||
|
||||
type Flagger interface {
|
||||
EnableReceiverNamesInMetrics() bool
|
||||
ClassicMode() bool
|
||||
UTF8StrictMode() bool
|
||||
EnableAutoGOMEMLIMIT() bool
|
||||
EnableAutoGOMAXPROCS() bool
|
||||
}
|
||||
|
||||
type Flags struct {
|
||||
logger log.Logger
|
||||
logger *slog.Logger
|
||||
enableReceiverNamesInMetrics bool
|
||||
classicMode bool
|
||||
utf8StrictMode bool
|
||||
enableAutoGOMEMLIMIT bool
|
||||
enableAutoGOMAXPROCS bool
|
||||
}
|
||||
|
||||
func (f *Flags) EnableReceiverNamesInMetrics() bool {
|
||||
@@ -59,6 +65,14 @@ func (f *Flags) UTF8StrictMode() bool {
|
||||
return f.utf8StrictMode
|
||||
}
|
||||
|
||||
func (f *Flags) EnableAutoGOMEMLIMIT() bool {
|
||||
return f.enableAutoGOMEMLIMIT
|
||||
}
|
||||
|
||||
func (f *Flags) EnableAutoGOMAXPROCS() bool {
|
||||
return f.enableAutoGOMAXPROCS
|
||||
}
|
||||
|
||||
type flagOption func(flags *Flags)
|
||||
|
||||
func enableReceiverNameInMetrics() flagOption {
|
||||
@@ -79,7 +93,19 @@ func enableUTF8StrictMode() flagOption {
|
||||
}
|
||||
}
|
||||
|
||||
func NewFlags(logger log.Logger, features string) (Flagger, error) {
|
||||
func enableAutoGOMEMLIMIT() flagOption {
|
||||
return func(configs *Flags) {
|
||||
configs.enableAutoGOMEMLIMIT = true
|
||||
}
|
||||
}
|
||||
|
||||
func enableAutoGOMAXPROCS() flagOption {
|
||||
return func(configs *Flags) {
|
||||
configs.enableAutoGOMAXPROCS = true
|
||||
}
|
||||
}
|
||||
|
||||
func NewFlags(logger *slog.Logger, features string) (Flagger, error) {
|
||||
fc := &Flags{logger: logger}
|
||||
opts := []flagOption{}
|
||||
|
||||
@@ -91,13 +117,19 @@ func NewFlags(logger log.Logger, features string) (Flagger, error) {
|
||||
switch feature {
|
||||
case FeatureReceiverNameInMetrics:
|
||||
opts = append(opts, enableReceiverNameInMetrics())
|
||||
level.Warn(logger).Log("msg", "Experimental receiver name in metrics enabled")
|
||||
logger.Warn("Experimental receiver name in metrics enabled")
|
||||
case FeatureClassicMode:
|
||||
opts = append(opts, enableClassicMode())
|
||||
level.Warn(logger).Log("msg", "Classic mode enabled")
|
||||
logger.Warn("Classic mode enabled")
|
||||
case FeatureUTF8StrictMode:
|
||||
opts = append(opts, enableUTF8StrictMode())
|
||||
level.Warn(logger).Log("msg", "UTF-8 strict mode enabled")
|
||||
logger.Warn("UTF-8 strict mode enabled")
|
||||
case FeatureAutoGOMEMLIMIT:
|
||||
opts = append(opts, enableAutoGOMEMLIMIT())
|
||||
logger.Warn("Automatically set GOMEMLIMIT to match the Linux container or system memory limit.")
|
||||
case FeatureAutoGOMAXPROCS:
|
||||
opts = append(opts, enableAutoGOMAXPROCS())
|
||||
logger.Warn("Automatically set GOMAXPROCS to match Linux container CPU quota")
|
||||
default:
|
||||
return nil, fmt.Errorf("Unknown option '%s' for --enable-feature", feature)
|
||||
}
|
||||
@@ -121,3 +153,7 @@ func (n NoopFlags) EnableReceiverNamesInMetrics() bool { return false }
|
||||
func (n NoopFlags) ClassicMode() bool { return false }
|
||||
|
||||
func (n NoopFlags) UTF8StrictMode() bool { return false }
|
||||
|
||||
func (n NoopFlags) EnableAutoGOMEMLIMIT() bool { return false }
|
||||
|
||||
func (n NoopFlags) EnableAutoGOMAXPROCS() bool { return false }
|
||||
|
||||
@@ -15,23 +15,23 @@ package compat
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"reflect"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/common/model"
|
||||
"github.com/prometheus/common/promslog"
|
||||
|
||||
"github.com/prometheus/alertmanager/featurecontrol"
|
||||
"github.com/prometheus/alertmanager/matchers/parse"
|
||||
"github.com/prometheus/alertmanager/matcher/parse"
|
||||
"github.com/prometheus/alertmanager/pkg/labels"
|
||||
)
|
||||
|
||||
var (
|
||||
isValidLabelName = isValidClassicLabelName(log.NewNopLogger())
|
||||
parseMatcher = ClassicMatcherParser(log.NewNopLogger())
|
||||
parseMatchers = ClassicMatchersParser(log.NewNopLogger())
|
||||
isValidLabelName = isValidClassicLabelName(promslog.NewNopLogger())
|
||||
parseMatcher = ClassicMatcherParser(promslog.NewNopLogger())
|
||||
parseMatchers = ClassicMatchersParser(promslog.NewNopLogger())
|
||||
)
|
||||
|
||||
// IsValidLabelName returns true if the string is a valid label name.
|
||||
@@ -56,7 +56,7 @@ func Matchers(input, origin string) (labels.Matchers, error) {
|
||||
}
|
||||
|
||||
// InitFromFlags initializes the compat package from the flagger.
|
||||
func InitFromFlags(l log.Logger, f featurecontrol.Flagger) {
|
||||
func InitFromFlags(l *slog.Logger, f featurecontrol.Flagger) {
|
||||
if f.ClassicMode() {
|
||||
isValidLabelName = isValidClassicLabelName(l)
|
||||
parseMatcher = ClassicMatcherParser(l)
|
||||
@@ -74,27 +74,27 @@ func InitFromFlags(l log.Logger, f featurecontrol.Flagger) {
|
||||
|
||||
// ClassicMatcherParser uses the pkg/labels parser to parse the matcher in
|
||||
// the input string.
|
||||
func ClassicMatcherParser(l log.Logger) ParseMatcher {
|
||||
func ClassicMatcherParser(l *slog.Logger) ParseMatcher {
|
||||
return func(input, origin string) (matcher *labels.Matcher, err error) {
|
||||
level.Debug(l).Log("msg", "Parsing with classic matchers parser", "input", input, "origin", origin)
|
||||
l.Debug("Parsing with classic matchers parser", "input", input, "origin", origin)
|
||||
return labels.ParseMatcher(input)
|
||||
}
|
||||
}
|
||||
|
||||
// ClassicMatchersParser uses the pkg/labels parser to parse zero or more
|
||||
// matchers in the input string. It returns an error if the input is invalid.
|
||||
func ClassicMatchersParser(l log.Logger) ParseMatchers {
|
||||
func ClassicMatchersParser(l *slog.Logger) ParseMatchers {
|
||||
return func(input, origin string) (matchers labels.Matchers, err error) {
|
||||
level.Debug(l).Log("msg", "Parsing with classic matchers parser", "input", input, "origin", origin)
|
||||
l.Debug("Parsing with classic matchers parser", "input", input, "origin", origin)
|
||||
return labels.ParseMatchers(input)
|
||||
}
|
||||
}
|
||||
|
||||
// UTF8MatcherParser uses the new matchers/parse parser to parse the matcher
|
||||
// UTF8MatcherParser uses the new matcher/parse parser to parse the matcher
|
||||
// in the input string. If this fails it does not revert to the pkg/labels parser.
|
||||
func UTF8MatcherParser(l log.Logger) ParseMatcher {
|
||||
func UTF8MatcherParser(l *slog.Logger) ParseMatcher {
|
||||
return func(input, origin string) (matcher *labels.Matcher, err error) {
|
||||
level.Debug(l).Log("msg", "Parsing with UTF-8 matchers parser", "input", input, "origin", origin)
|
||||
l.Debug("Parsing with UTF-8 matchers parser", "input", input, "origin", origin)
|
||||
if strings.HasPrefix(input, "{") || strings.HasSuffix(input, "}") {
|
||||
return nil, fmt.Errorf("unexpected open or close brace: %s", input)
|
||||
}
|
||||
@@ -102,22 +102,22 @@ func UTF8MatcherParser(l log.Logger) ParseMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
// UTF8MatchersParser uses the new matchers/parse parser to parse zero or more
|
||||
// UTF8MatchersParser uses the new matcher/parse parser to parse zero or more
|
||||
// matchers in the input string. If this fails it does not revert to the
|
||||
// pkg/labels parser.
|
||||
func UTF8MatchersParser(l log.Logger) ParseMatchers {
|
||||
func UTF8MatchersParser(l *slog.Logger) ParseMatchers {
|
||||
return func(input, origin string) (matchers labels.Matchers, err error) {
|
||||
level.Debug(l).Log("msg", "Parsing with UTF-8 matchers parser", "input", input, "origin", origin)
|
||||
l.Debug("Parsing with UTF-8 matchers parser", "input", input, "origin", origin)
|
||||
return parse.Matchers(input)
|
||||
}
|
||||
}
|
||||
|
||||
// FallbackMatcherParser uses the new matchers/parse parser to parse zero or more
|
||||
// FallbackMatcherParser uses the new matcher/parse parser to parse zero or more
|
||||
// matchers in the string. If this fails it reverts to the pkg/labels parser and
|
||||
// emits a warning log line.
|
||||
func FallbackMatcherParser(l log.Logger) ParseMatcher {
|
||||
func FallbackMatcherParser(l *slog.Logger) ParseMatcher {
|
||||
return func(input, origin string) (matcher *labels.Matcher, err error) {
|
||||
level.Debug(l).Log("msg", "Parsing with UTF-8 matchers parser, with fallback to classic matchers parser", "input", input, "origin", origin)
|
||||
l.Debug("Parsing with UTF-8 matchers parser, with fallback to classic matchers parser", "input", input, "origin", origin)
|
||||
if strings.HasPrefix(input, "{") || strings.HasSuffix(input, "}") {
|
||||
return nil, fmt.Errorf("unexpected open or close brace: %s", input)
|
||||
}
|
||||
@@ -130,28 +130,28 @@ func FallbackMatcherParser(l log.Logger) ParseMatcher {
|
||||
if cErr != nil {
|
||||
return nil, cErr
|
||||
}
|
||||
// The input is valid in the pkg/labels parser, but not the matchers/parse
|
||||
// The input is valid in the pkg/labels parser, but not the matcher/parse
|
||||
// parser. This means the input is not forwards compatible.
|
||||
suggestion := cMatcher.String()
|
||||
level.Warn(l).Log("msg", "Alertmanager is moving to a new parser for labels and matchers, and this input is incompatible. Alertmanager has instead parsed the input using the classic matchers parser as a fallback. To make this input compatible with the UTF-8 matchers parser please make sure all regular expressions and values are double-quoted. If you are still seeing this message please open an issue.", "input", input, "origin", origin, "err", nErr, "suggestion", suggestion)
|
||||
l.Warn("Alertmanager is moving to a new parser for labels and matchers, and this input is incompatible. Alertmanager has instead parsed the input using the classic matchers parser as a fallback. To make this input compatible with the UTF-8 matchers parser please make sure all regular expressions and values are double-quoted and backslashes are escaped. If you are still seeing this message please open an issue.", "input", input, "origin", origin, "err", nErr, "suggestion", suggestion)
|
||||
return cMatcher, nil
|
||||
}
|
||||
// If the input is valid in both parsers, but produces different results,
|
||||
// then there is disagreement.
|
||||
if nErr == nil && cErr == nil && !reflect.DeepEqual(nMatcher, cMatcher) {
|
||||
level.Warn(l).Log("msg", "Matchers input has disagreement", "input", input, "origin", origin)
|
||||
l.Warn("Matchers input has disagreement", "input", input, "origin", origin)
|
||||
return cMatcher, nil
|
||||
}
|
||||
return nMatcher, nil
|
||||
}
|
||||
}
|
||||
|
||||
// FallbackMatchersParser uses the new matchers/parse parser to parse the
|
||||
// FallbackMatchersParser uses the new matcher/parse parser to parse the
|
||||
// matcher in the input string. If this fails it falls back to the pkg/labels
|
||||
// parser and emits a warning log line.
|
||||
func FallbackMatchersParser(l log.Logger) ParseMatchers {
|
||||
func FallbackMatchersParser(l *slog.Logger) ParseMatchers {
|
||||
return func(input, origin string) (matchers labels.Matchers, err error) {
|
||||
level.Debug(l).Log("msg", "Parsing with UTF-8 matchers parser, with fallback to classic matchers parser", "input", input, "origin", origin)
|
||||
l.Debug("Parsing with UTF-8 matchers parser, with fallback to classic matchers parser", "input", input, "origin", origin)
|
||||
// Parse the input in both parsers to look for disagreement and incompatible
|
||||
// inputs.
|
||||
nMatchers, nErr := parse.Matchers(input)
|
||||
@@ -161,7 +161,7 @@ func FallbackMatchersParser(l log.Logger) ParseMatchers {
|
||||
if cErr != nil {
|
||||
return nil, cErr
|
||||
}
|
||||
// The input is valid in the pkg/labels parser, but not the matchers/parse
|
||||
// The input is valid in the pkg/labels parser, but not the matcher/parse
|
||||
// parser. This means the input is not forwards compatible.
|
||||
var sb strings.Builder
|
||||
for i, n := range cMatchers {
|
||||
@@ -172,15 +172,15 @@ func FallbackMatchersParser(l log.Logger) ParseMatchers {
|
||||
}
|
||||
suggestion := sb.String()
|
||||
// The input is valid in the pkg/labels parser, but not the
|
||||
// new matchers/parse parser.
|
||||
level.Warn(l).Log("msg", "Alertmanager is moving to a new parser for labels and matchers, and this input is incompatible. Alertmanager has instead parsed the input using the classic matchers parser as a fallback. To make this input compatible with the UTF-8 matchers parser please make sure all regular expressions and values are double-quoted. If you are still seeing this message please open an issue.", "input", input, "origin", origin, "err", nErr, "suggestion", suggestion)
|
||||
// new matcher/parse parser.
|
||||
l.Warn("Alertmanager is moving to a new parser for labels and matchers, and this input is incompatible. Alertmanager has instead parsed the input using the classic matchers parser as a fallback. To make this input compatible with the UTF-8 matchers parser please make sure all regular expressions and values are double-quoted and backslashes are escaped. If you are still seeing this message please open an issue.", "input", input, "origin", origin, "err", nErr, "suggestion", suggestion)
|
||||
return cMatchers, nil
|
||||
}
|
||||
// If the input is valid in both parsers, but produces different results,
|
||||
// then there is disagreement. We need to compare to labels.Matchers(cMatchers)
|
||||
// as cMatchers is a []*labels.Matcher not labels.Matchers.
|
||||
if nErr == nil && cErr == nil && !reflect.DeepEqual(nMatchers, labels.Matchers(cMatchers)) {
|
||||
level.Warn(l).Log("msg", "Matchers input has disagreement", "input", input, "origin", origin)
|
||||
l.Warn("Matchers input has disagreement", "input", input, "origin", origin)
|
||||
return cMatchers, nil
|
||||
}
|
||||
return nMatchers, nil
|
||||
@@ -188,14 +188,14 @@ func FallbackMatchersParser(l log.Logger) ParseMatchers {
|
||||
}
|
||||
|
||||
// isValidClassicLabelName returns true if the string is a valid classic label name.
|
||||
func isValidClassicLabelName(_ log.Logger) func(model.LabelName) bool {
|
||||
func isValidClassicLabelName(_ *slog.Logger) func(model.LabelName) bool {
|
||||
return func(name model.LabelName) bool {
|
||||
return name.IsValid()
|
||||
}
|
||||
}
|
||||
|
||||
// isValidUTF8LabelName returns true if the string is a valid UTF-8 label name.
|
||||
func isValidUTF8LabelName(_ log.Logger) func(model.LabelName) bool {
|
||||
func isValidUTF8LabelName(_ *slog.Logger) func(model.LabelName) bool {
|
||||
return func(name model.LabelName) bool {
|
||||
if len(name) == 0 {
|
||||
return false
|
||||
@@ -251,7 +251,7 @@ func (l *lexer) accept(valid string) bool {
|
||||
}
|
||||
|
||||
// expect consumes the next rune if its one of the valid runes.
|
||||
// it returns nil if the next rune is valid, otherwise an expectedError
|
||||
// It returns nil if the next rune is valid, otherwise an expectedError
|
||||
// error.
|
||||
func (l *lexer) expect(valid string) error {
|
||||
if strings.ContainsRune(valid, l.next()) {
|
||||
@@ -196,7 +196,7 @@ func (p *parser) parseEndOfMatcher(l *lexer) (parseFunc, error) {
|
||||
if err != nil {
|
||||
if errors.Is(err, errEOF) {
|
||||
// If this is the end of input we still need to check if the optional
|
||||
// open brace has a matching close brace
|
||||
// open brace has a matching close brace.
|
||||
return p.parseCloseBrace, nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %w", err, errExpectedCommaOrCloseBrace)
|
||||
@@ -220,7 +220,7 @@ func (p *parser) parseComma(l *lexer) (parseFunc, error) {
|
||||
if err != nil {
|
||||
if errors.Is(err, errEOF) {
|
||||
// If this is the end of input we still need to check if the optional
|
||||
// open brace has a matching close brace
|
||||
// open brace has a matching close brace.
|
||||
return p.parseCloseBrace, nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: %w", err, errExpectedMatcherOrCloseBrace)
|
||||
@@ -242,6 +242,7 @@ func (p *parser) parseEOF(l *lexer) (parseFunc, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// nolint:godot
|
||||
// accept returns true if the next token is one of the specified kinds,
|
||||
// otherwise false. If the token is accepted it is consumed. tokenEOF is
|
||||
// not an accepted kind and instead accept returns ErrEOF if there is no
|
||||
@@ -256,6 +257,7 @@ func (p *parser) accept(l *lexer, kinds ...tokenKind) (ok bool, err error) {
|
||||
return ok, err
|
||||
}
|
||||
|
||||
// nolint:godot
|
||||
// acceptPeek returns true if the next token is one of the specified kinds,
|
||||
// otherwise false. However, unlike accept, acceptPeek does not consume accepted
|
||||
// tokens. tokenEOF is not an accepted kind and instead accept returns ErrEOF
|
||||
@@ -271,6 +273,7 @@ func (p *parser) acceptPeek(l *lexer, kinds ...tokenKind) (bool, error) {
|
||||
return t.isOneOf(kinds...), nil
|
||||
}
|
||||
|
||||
// nolint:godot
|
||||
// expect returns the next token if it is one of the specified kinds, otherwise
|
||||
// it returns an error. If the token is expected it is consumed. tokenEOF is not
|
||||
// an accepted kind and instead expect returns ErrEOF if there is no more input.
|
||||
@@ -285,6 +288,7 @@ func (p *parser) expect(l *lexer, kind ...tokenKind) (token, error) {
|
||||
return t, nil
|
||||
}
|
||||
|
||||
// nolint:godot
|
||||
// expect returns the next token if it is one of the specified kinds, otherwise
|
||||
// it returns an error. However, unlike expect, expectPeek does not consume tokens.
|
||||
// tokenEOF is not an accepted kind and instead expect returns ErrEOF if there is no
|
||||
2
vendor/github.com/prometheus/alertmanager/pkg/labels/matcher.go
generated
vendored
2
vendor/github.com/prometheus/alertmanager/pkg/labels/matcher.go
generated
vendored
@@ -205,7 +205,7 @@ func (ms Matchers) String() string {
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// This is copied from matchers/parse/lexer.go. It will be removed when
|
||||
// This is copied from matcher/parse/lexer.go. It will be removed when
|
||||
// the transition window from classic matchers to UTF-8 matchers is complete,
|
||||
// as then we can use double quotes when printing the label name for all
|
||||
// matchers. Until then, the classic parser does not understand double quotes
|
||||
|
||||
2
vendor/github.com/prometheus/alertmanager/pkg/labels/parse.go
generated
vendored
2
vendor/github.com/prometheus/alertmanager/pkg/labels/parse.go
generated
vendored
@@ -136,7 +136,7 @@ func ParseMatcher(s string) (_ *Matcher, err error) {
|
||||
return nil, fmt.Errorf("matcher value not valid UTF-8: %s", ms[3])
|
||||
}
|
||||
|
||||
// Unescape the rawValue:
|
||||
// Unescape the rawValue.
|
||||
for i, r := range rawValue {
|
||||
if escaped {
|
||||
escaped = false
|
||||
|
||||
4
vendor/github.com/prometheus/alertmanager/template/Dockerfile
generated
vendored
4
vendor/github.com/prometheus/alertmanager/template/Dockerfile
generated
vendored
@@ -1,7 +1,7 @@
|
||||
FROM node
|
||||
FROM node:20-alpine
|
||||
|
||||
ENV NODE_PATH="/usr/local/lib/node_modules"
|
||||
|
||||
RUN npm install juice -g
|
||||
RUN npm install juice@10.0.1 -g
|
||||
|
||||
ENTRYPOINT [""]
|
||||
|
||||
2
vendor/github.com/prometheus/alertmanager/template/Makefile
generated
vendored
2
vendor/github.com/prometheus/alertmanager/template/Makefile
generated
vendored
@@ -1,4 +1,4 @@
|
||||
DOCKER_IMG := altermanager-template
|
||||
DOCKER_IMG := alertmanager-template
|
||||
DOCKER_RUN_CURRENT_USER := docker run --user=$(shell id -u $(USER)):$(shell id -g $(USER))
|
||||
DOCKER_CMD := $(DOCKER_RUN_CURRENT_USER) --rm -t -v $(PWD):/app -w /app $(DOCKER_IMG)
|
||||
|
||||
|
||||
59
vendor/github.com/prometheus/alertmanager/template/default.tmpl
generated
vendored
59
vendor/github.com/prometheus/alertmanager/template/default.tmpl
generated
vendored
@@ -123,6 +123,7 @@ Alerts Resolved:
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ define "discord.default.content" }}{{ end }}
|
||||
{{ define "discord.default.title" }}{{ template "__subject" . }}{{ end }}
|
||||
{{ define "discord.default.message" }}
|
||||
{{ if gt (len .Alerts.Firing) 0 }}
|
||||
@@ -158,3 +159,61 @@ Alerts Resolved:
|
||||
{{ template "__text_alert_list_markdown" .Alerts.Resolved }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ define "msteamsv2.default.title" }}{{ template "__subject" . }}{{ end }}
|
||||
{{ define "msteamsv2.default.text" }}
|
||||
{{ if gt (len .Alerts.Firing) 0 }}
|
||||
# Alerts Firing:
|
||||
{{ template "__text_alert_list_markdown" .Alerts.Firing }}
|
||||
{{ end }}
|
||||
{{ if gt (len .Alerts.Resolved) 0 }}
|
||||
# Alerts Resolved:
|
||||
{{ template "__text_alert_list_markdown" .Alerts.Resolved }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ define "jira.default.summary" }}{{ template "__subject" . }}{{ end }}
|
||||
{{ define "jira.default.description" }}
|
||||
{{ if gt (len .Alerts.Firing) 0 }}
|
||||
# Alerts Firing:
|
||||
{{ template "__text_alert_list_markdown" .Alerts.Firing }}
|
||||
{{ end }}
|
||||
{{ if gt (len .Alerts.Resolved) 0 }}
|
||||
# Alerts Resolved:
|
||||
{{ template "__text_alert_list_markdown" .Alerts.Resolved }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{- define "jira.default.priority" -}}
|
||||
{{- $priority := "" }}
|
||||
{{- range .Alerts.Firing -}}
|
||||
{{- $severity := index .Labels "severity" -}}
|
||||
{{- if (eq $severity "critical") -}}
|
||||
{{- $priority = "High" -}}
|
||||
{{- else if (and (eq $severity "warning") (ne $priority "High")) -}}
|
||||
{{- $priority = "Medium" -}}
|
||||
{{- else if (and (eq $severity "info") (eq $priority "")) -}}
|
||||
{{- $priority = "Low" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- if eq $priority "" -}}
|
||||
{{- range .Alerts.Resolved -}}
|
||||
{{- $severity := index .Labels "severity" -}}
|
||||
{{- if (eq $severity "critical") -}}
|
||||
{{- $priority = "High" -}}
|
||||
{{- else if (and (eq $severity "warning") (ne $priority "High")) -}}
|
||||
{{- $priority = "Medium" -}}
|
||||
{{- else if (and (eq $severity "info") (eq $priority "")) -}}
|
||||
{{- $priority = "Low" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- $priority -}}
|
||||
{{- end -}}
|
||||
|
||||
{{ define "rocketchat.default.title" }}{{ template "__subject" . }}{{ end }}
|
||||
{{ define "rocketchat.default.alias" }}{{ template "__alertmanager" . }}{{ end }}
|
||||
{{ define "rocketchat.default.titlelink" }}{{ template "__alertmanagerURL" . }}{{ end }}
|
||||
{{ define "rocketchat.default.emoji" }}{{ end }}
|
||||
{{ define "rocketchat.default.iconurl" }}{{ end }}
|
||||
{{ define "rocketchat.default.text" }}{{ end }}
|
||||
|
||||
15
vendor/github.com/prometheus/alertmanager/template/template.go
generated
vendored
15
vendor/github.com/prometheus/alertmanager/template/template.go
generated
vendored
@@ -26,6 +26,7 @@ import (
|
||||
tmpltext "text/template"
|
||||
"time"
|
||||
|
||||
commonTemplates "github.com/prometheus/common/helpers/templates"
|
||||
"github.com/prometheus/common/model"
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
@@ -192,6 +193,20 @@ var DefaultFuncs = FuncMap{
|
||||
"stringSlice": func(s ...string) []string {
|
||||
return s
|
||||
},
|
||||
// date returns the text representation of the time in the specified format.
|
||||
"date": func(fmt string, t time.Time) string {
|
||||
return t.Format(fmt)
|
||||
},
|
||||
// tz returns the time in the timezone.
|
||||
"tz": func(name string, t time.Time) (time.Time, error) {
|
||||
loc, err := time.LoadLocation(name)
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
return t.In(loc), nil
|
||||
},
|
||||
"since": time.Since,
|
||||
"humanizeDuration": commonTemplates.HumanizeDuration,
|
||||
}
|
||||
|
||||
// Pair is a key/value string pair.
|
||||
|
||||
142
vendor/github.com/prometheus/alertmanager/types/types.go
generated
vendored
142
vendor/github.com/prometheus/alertmanager/types/types.go
generated
vendored
@@ -22,7 +22,7 @@ import (
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/common/model"
|
||||
|
||||
"github.com/prometheus/alertmanager/matchers/compat"
|
||||
"github.com/prometheus/alertmanager/matcher/compat"
|
||||
"github.com/prometheus/alertmanager/pkg/labels"
|
||||
)
|
||||
|
||||
@@ -52,9 +52,17 @@ type AlertStatus struct {
|
||||
silencesVersion int
|
||||
}
|
||||
|
||||
// Marker helps to mark alerts as silenced and/or inhibited.
|
||||
// groupStatus stores the state of the group, and, as applicable, the names
|
||||
// of all active and mute time intervals that are muting it.
|
||||
type groupStatus struct {
|
||||
// mutedBy contains the names of all active and mute time intervals that
|
||||
// are muting it.
|
||||
mutedBy []string
|
||||
}
|
||||
|
||||
// AlertMarker helps to mark alerts as silenced and/or inhibited.
|
||||
// All methods are goroutine-safe.
|
||||
type Marker interface {
|
||||
type AlertMarker interface {
|
||||
// SetActiveOrSilenced replaces the previous SilencedBy by the provided IDs of
|
||||
// active and pending silences, including the version number of the
|
||||
// silences state. The set of provided IDs is supposed to represent the
|
||||
@@ -92,24 +100,74 @@ type Marker interface {
|
||||
Inhibited(model.Fingerprint) ([]string, bool)
|
||||
}
|
||||
|
||||
// NewMarker returns an instance of a Marker implementation.
|
||||
func NewMarker(r prometheus.Registerer) Marker {
|
||||
m := &memMarker{
|
||||
m: map[model.Fingerprint]*AlertStatus{},
|
||||
// GroupMarker helps to mark groups as active or muted.
|
||||
// All methods are goroutine-safe.
|
||||
//
|
||||
// TODO(grobinson): routeID is used in Muted and SetMuted because groupKey
|
||||
// is not unique (see #3817). Once groupKey uniqueness is fixed routeID can
|
||||
// be removed from the GroupMarker interface.
|
||||
type GroupMarker interface {
|
||||
// Muted returns true if the group is muted, otherwise false. If the group
|
||||
// is muted then it also returns the names of the time intervals that muted
|
||||
// it.
|
||||
Muted(routeID, groupKey string) ([]string, bool)
|
||||
|
||||
// SetMuted marks the group as muted, and sets the names of the time
|
||||
// intervals that mute it. If the list of names is nil or the empty slice
|
||||
// then the muted marker is removed.
|
||||
SetMuted(routeID, groupKey string, timeIntervalNames []string)
|
||||
|
||||
// DeleteByGroupKey removes all markers for the GroupKey.
|
||||
DeleteByGroupKey(routeID, groupKey string)
|
||||
}
|
||||
|
||||
// NewMarker returns an instance of a AlertMarker implementation.
|
||||
func NewMarker(r prometheus.Registerer) *MemMarker {
|
||||
m := &MemMarker{
|
||||
alerts: map[model.Fingerprint]*AlertStatus{},
|
||||
groups: map[string]*groupStatus{},
|
||||
}
|
||||
|
||||
m.registerMetrics(r)
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
type memMarker struct {
|
||||
m map[model.Fingerprint]*AlertStatus
|
||||
type MemMarker struct {
|
||||
alerts map[model.Fingerprint]*AlertStatus
|
||||
groups map[string]*groupStatus
|
||||
|
||||
mtx sync.RWMutex
|
||||
}
|
||||
|
||||
func (m *memMarker) registerMetrics(r prometheus.Registerer) {
|
||||
// Muted implements GroupMarker.
|
||||
func (m *MemMarker) Muted(routeID, groupKey string) ([]string, bool) {
|
||||
m.mtx.Lock()
|
||||
defer m.mtx.Unlock()
|
||||
status, ok := m.groups[routeID+groupKey]
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
return status.mutedBy, len(status.mutedBy) > 0
|
||||
}
|
||||
|
||||
// SetMuted implements GroupMarker.
|
||||
func (m *MemMarker) SetMuted(routeID, groupKey string, timeIntervalNames []string) {
|
||||
m.mtx.Lock()
|
||||
defer m.mtx.Unlock()
|
||||
status, ok := m.groups[routeID+groupKey]
|
||||
if !ok {
|
||||
status = &groupStatus{}
|
||||
m.groups[routeID+groupKey] = status
|
||||
}
|
||||
status.mutedBy = timeIntervalNames
|
||||
}
|
||||
|
||||
func (m *MemMarker) DeleteByGroupKey(routeID, groupKey string) {
|
||||
m.mtx.Lock()
|
||||
defer m.mtx.Unlock()
|
||||
delete(m.groups, routeID+groupKey)
|
||||
}
|
||||
|
||||
func (m *MemMarker) registerMetrics(r prometheus.Registerer) {
|
||||
newMarkedAlertMetricByState := func(st AlertState) prometheus.GaugeFunc {
|
||||
return prometheus.NewGaugeFunc(
|
||||
prometheus.GaugeOpts{
|
||||
@@ -132,17 +190,17 @@ func (m *memMarker) registerMetrics(r prometheus.Registerer) {
|
||||
r.MustRegister(alertStateUnprocessed)
|
||||
}
|
||||
|
||||
// Count implements Marker.
|
||||
func (m *memMarker) Count(states ...AlertState) int {
|
||||
// Count implements AlertMarker.
|
||||
func (m *MemMarker) Count(states ...AlertState) int {
|
||||
m.mtx.RLock()
|
||||
defer m.mtx.RUnlock()
|
||||
|
||||
if len(states) == 0 {
|
||||
return len(m.m)
|
||||
return len(m.alerts)
|
||||
}
|
||||
|
||||
var count int
|
||||
for _, status := range m.m {
|
||||
for _, status := range m.alerts {
|
||||
for _, state := range states {
|
||||
if status.State == state {
|
||||
count++
|
||||
@@ -152,15 +210,15 @@ func (m *memMarker) Count(states ...AlertState) int {
|
||||
return count
|
||||
}
|
||||
|
||||
// SetActiveOrSilenced implements Marker.
|
||||
func (m *memMarker) SetActiveOrSilenced(alert model.Fingerprint, version int, activeIDs, pendingIDs []string) {
|
||||
// SetActiveOrSilenced implements AlertMarker.
|
||||
func (m *MemMarker) SetActiveOrSilenced(alert model.Fingerprint, version int, activeIDs, pendingIDs []string) {
|
||||
m.mtx.Lock()
|
||||
defer m.mtx.Unlock()
|
||||
|
||||
s, found := m.m[alert]
|
||||
s, found := m.alerts[alert]
|
||||
if !found {
|
||||
s = &AlertStatus{}
|
||||
m.m[alert] = s
|
||||
m.alerts[alert] = s
|
||||
}
|
||||
s.SilencedBy = activeIDs
|
||||
s.pendingSilences = pendingIDs
|
||||
@@ -177,15 +235,15 @@ func (m *memMarker) SetActiveOrSilenced(alert model.Fingerprint, version int, ac
|
||||
s.State = AlertStateSuppressed
|
||||
}
|
||||
|
||||
// SetInhibited implements Marker.
|
||||
func (m *memMarker) SetInhibited(alert model.Fingerprint, ids ...string) {
|
||||
// SetInhibited implements AlertMarker.
|
||||
func (m *MemMarker) SetInhibited(alert model.Fingerprint, ids ...string) {
|
||||
m.mtx.Lock()
|
||||
defer m.mtx.Unlock()
|
||||
|
||||
s, found := m.m[alert]
|
||||
s, found := m.alerts[alert]
|
||||
if !found {
|
||||
s = &AlertStatus{}
|
||||
m.m[alert] = s
|
||||
m.alerts[alert] = s
|
||||
}
|
||||
s.InhibitedBy = ids
|
||||
|
||||
@@ -200,12 +258,12 @@ func (m *memMarker) SetInhibited(alert model.Fingerprint, ids ...string) {
|
||||
s.State = AlertStateSuppressed
|
||||
}
|
||||
|
||||
// Status implements Marker.
|
||||
func (m *memMarker) Status(alert model.Fingerprint) AlertStatus {
|
||||
// Status implements AlertMarker.
|
||||
func (m *MemMarker) Status(alert model.Fingerprint) AlertStatus {
|
||||
m.mtx.RLock()
|
||||
defer m.mtx.RUnlock()
|
||||
|
||||
if s, found := m.m[alert]; found {
|
||||
if s, found := m.alerts[alert]; found {
|
||||
return *s
|
||||
}
|
||||
return AlertStatus{
|
||||
@@ -215,26 +273,26 @@ func (m *memMarker) Status(alert model.Fingerprint) AlertStatus {
|
||||
}
|
||||
}
|
||||
|
||||
// Delete implements Marker.
|
||||
func (m *memMarker) Delete(alert model.Fingerprint) {
|
||||
// Delete implements AlertMarker.
|
||||
func (m *MemMarker) Delete(alert model.Fingerprint) {
|
||||
m.mtx.Lock()
|
||||
defer m.mtx.Unlock()
|
||||
|
||||
delete(m.m, alert)
|
||||
delete(m.alerts, alert)
|
||||
}
|
||||
|
||||
// Unprocessed implements Marker.
|
||||
func (m *memMarker) Unprocessed(alert model.Fingerprint) bool {
|
||||
// Unprocessed implements AlertMarker.
|
||||
func (m *MemMarker) Unprocessed(alert model.Fingerprint) bool {
|
||||
return m.Status(alert).State == AlertStateUnprocessed
|
||||
}
|
||||
|
||||
// Active implements Marker.
|
||||
func (m *memMarker) Active(alert model.Fingerprint) bool {
|
||||
// Active implements AlertMarker.
|
||||
func (m *MemMarker) Active(alert model.Fingerprint) bool {
|
||||
return m.Status(alert).State == AlertStateActive
|
||||
}
|
||||
|
||||
// Inhibited implements Marker.
|
||||
func (m *memMarker) Inhibited(alert model.Fingerprint) ([]string, bool) {
|
||||
// Inhibited implements AlertMarker.
|
||||
func (m *MemMarker) Inhibited(alert model.Fingerprint) ([]string, bool) {
|
||||
s := m.Status(alert)
|
||||
return s.InhibitedBy,
|
||||
s.State == AlertStateSuppressed && len(s.InhibitedBy) > 0
|
||||
@@ -243,7 +301,7 @@ func (m *memMarker) Inhibited(alert model.Fingerprint) ([]string, bool) {
|
||||
// Silenced returns whether the alert for the given Fingerprint is in the
|
||||
// Silenced state, any associated silence IDs, and the silences state version
|
||||
// the result is based on.
|
||||
func (m *memMarker) Silenced(alert model.Fingerprint) (activeIDs, pendingIDs []string, version int, silenced bool) {
|
||||
func (m *MemMarker) Silenced(alert model.Fingerprint) (activeIDs, pendingIDs []string, version int, silenced bool) {
|
||||
s := m.Status(alert)
|
||||
return s.SilencedBy, s.pendingSilences, s.silencesVersion,
|
||||
s.State == AlertStateSuppressed && len(s.SilencedBy) > 0
|
||||
@@ -410,15 +468,17 @@ func (a *Alert) Merge(o *Alert) *Alert {
|
||||
}
|
||||
|
||||
// A Muter determines whether a given label set is muted. Implementers that
|
||||
// maintain an underlying Marker are expected to update it during a call of
|
||||
// maintain an underlying AlertMarker are expected to update it during a call of
|
||||
// Mutes.
|
||||
type Muter interface {
|
||||
Mutes(model.LabelSet) bool
|
||||
}
|
||||
|
||||
// TimeMuter determines if alerts should be muted based on the specified current time and active time interval on the route.
|
||||
// A TimeMuter determines if the time is muted by one or more active or mute
|
||||
// time intervals. If the time is muted, it returns true and the names of the
|
||||
// time intervals that muted it. Otherwise, it returns false and a nil slice.
|
||||
type TimeMuter interface {
|
||||
Mutes(timeIntervalName []string, now time.Time) (bool, error)
|
||||
Mutes(timeIntervalNames []string, now time.Time) (bool, []string, error)
|
||||
}
|
||||
|
||||
// A MuteFunc is a function that implements the Muter interface.
|
||||
@@ -458,7 +518,7 @@ type Silence struct {
|
||||
}
|
||||
|
||||
// Expired return if the silence is expired
|
||||
// meaning that both StartsAt and EndsAt are equal
|
||||
// meaning that both StartsAt and EndsAt are equal.
|
||||
func (s *Silence) Expired() bool {
|
||||
return s.StartsAt.Equal(s.EndsAt)
|
||||
}
|
||||
|
||||
123
vendor/github.com/prometheus/common/helpers/templates/time.go
generated
vendored
Normal file
123
vendor/github.com/prometheus/common/helpers/templates/time.go
generated
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
// Copyright 2024 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package templates
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/common/model"
|
||||
)
|
||||
|
||||
var errNaNOrInf = errors.New("value is NaN or Inf")
|
||||
|
||||
func ConvertToFloat(i interface{}) (float64, error) {
|
||||
switch v := i.(type) {
|
||||
case float64:
|
||||
return v, nil
|
||||
case string:
|
||||
return strconv.ParseFloat(v, 64)
|
||||
case int:
|
||||
return float64(v), nil
|
||||
case uint:
|
||||
return float64(v), nil
|
||||
case int64:
|
||||
return float64(v), nil
|
||||
case uint64:
|
||||
return float64(v), nil
|
||||
case time.Duration:
|
||||
return v.Seconds(), nil
|
||||
default:
|
||||
return 0, fmt.Errorf("can't convert %T to float", v)
|
||||
}
|
||||
}
|
||||
|
||||
func FloatToTime(v float64) (*time.Time, error) {
|
||||
if math.IsNaN(v) || math.IsInf(v, 0) {
|
||||
return nil, errNaNOrInf
|
||||
}
|
||||
timestamp := v * 1e9
|
||||
if timestamp > math.MaxInt64 || timestamp < math.MinInt64 {
|
||||
return nil, fmt.Errorf("%v cannot be represented as a nanoseconds timestamp since it overflows int64", v)
|
||||
}
|
||||
t := model.TimeFromUnixNano(int64(timestamp)).Time().UTC()
|
||||
return &t, nil
|
||||
}
|
||||
|
||||
func HumanizeDuration(i interface{}) (string, error) {
|
||||
v, err := ConvertToFloat(i)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if math.IsNaN(v) || math.IsInf(v, 0) {
|
||||
return fmt.Sprintf("%.4g", v), nil
|
||||
}
|
||||
if v == 0 {
|
||||
return fmt.Sprintf("%.4gs", v), nil
|
||||
}
|
||||
if math.Abs(v) >= 1 {
|
||||
sign := ""
|
||||
if v < 0 {
|
||||
sign = "-"
|
||||
v = -v
|
||||
}
|
||||
duration := int64(v)
|
||||
seconds := duration % 60
|
||||
minutes := (duration / 60) % 60
|
||||
hours := (duration / 60 / 60) % 24
|
||||
days := duration / 60 / 60 / 24
|
||||
// For days to minutes, we display seconds as an integer.
|
||||
if days != 0 {
|
||||
return fmt.Sprintf("%s%dd %dh %dm %ds", sign, days, hours, minutes, seconds), nil
|
||||
}
|
||||
if hours != 0 {
|
||||
return fmt.Sprintf("%s%dh %dm %ds", sign, hours, minutes, seconds), nil
|
||||
}
|
||||
if minutes != 0 {
|
||||
return fmt.Sprintf("%s%dm %ds", sign, minutes, seconds), nil
|
||||
}
|
||||
// For seconds, we display 4 significant digits.
|
||||
return fmt.Sprintf("%s%.4gs", sign, v), nil
|
||||
}
|
||||
prefix := ""
|
||||
for _, p := range []string{"m", "u", "n", "p", "f", "a", "z", "y"} {
|
||||
if math.Abs(v) >= 1 {
|
||||
break
|
||||
}
|
||||
prefix = p
|
||||
v *= 1000
|
||||
}
|
||||
return fmt.Sprintf("%.4g%ss", v, prefix), nil
|
||||
}
|
||||
|
||||
func HumanizeTimestamp(i interface{}) (string, error) {
|
||||
v, err := ConvertToFloat(i)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
tm, err := FloatToTime(v)
|
||||
switch {
|
||||
case errors.Is(err, errNaNOrInf):
|
||||
return fmt.Sprintf("%.4g", v), nil
|
||||
case err != nil:
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprint(tm), nil
|
||||
}
|
||||
201
vendor/github.com/prometheus/common/promslog/slog.go
generated
vendored
Normal file
201
vendor/github.com/prometheus/common/promslog/slog.go
generated
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
// Copyright 2024 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package promslog defines standardised ways to initialize the Go standard
|
||||
// library's log/slog logger.
|
||||
// It should typically only ever be imported by main packages.
|
||||
|
||||
package promslog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type LogStyle string
|
||||
|
||||
const (
|
||||
SlogStyle LogStyle = "slog"
|
||||
GoKitStyle LogStyle = "go-kit"
|
||||
)
|
||||
|
||||
var (
|
||||
LevelFlagOptions = []string{"debug", "info", "warn", "error"}
|
||||
FormatFlagOptions = []string{"logfmt", "json"}
|
||||
|
||||
callerAddFunc = false
|
||||
defaultWriter = os.Stderr
|
||||
goKitStyleReplaceAttrFunc = func(groups []string, a slog.Attr) slog.Attr {
|
||||
key := a.Key
|
||||
switch key {
|
||||
case slog.TimeKey:
|
||||
a.Key = "ts"
|
||||
|
||||
// This timestamp format differs from RFC3339Nano by using .000 instead
|
||||
// of .999999999 which changes the timestamp from 9 variable to 3 fixed
|
||||
// decimals (.130 instead of .130987456).
|
||||
t := a.Value.Time()
|
||||
a.Value = slog.StringValue(t.UTC().Format("2006-01-02T15:04:05.000Z07:00"))
|
||||
case slog.SourceKey:
|
||||
a.Key = "caller"
|
||||
src, _ := a.Value.Any().(*slog.Source)
|
||||
|
||||
switch callerAddFunc {
|
||||
case true:
|
||||
a.Value = slog.StringValue(filepath.Base(src.File) + "(" + filepath.Base(src.Function) + "):" + strconv.Itoa(src.Line))
|
||||
default:
|
||||
a.Value = slog.StringValue(filepath.Base(src.File) + ":" + strconv.Itoa(src.Line))
|
||||
}
|
||||
case slog.LevelKey:
|
||||
a.Value = slog.StringValue(strings.ToLower(a.Value.String()))
|
||||
default:
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
defaultReplaceAttrFunc = func(groups []string, a slog.Attr) slog.Attr {
|
||||
key := a.Key
|
||||
switch key {
|
||||
case slog.TimeKey:
|
||||
t := a.Value.Time()
|
||||
a.Value = slog.TimeValue(t.UTC())
|
||||
case slog.SourceKey:
|
||||
src, _ := a.Value.Any().(*slog.Source)
|
||||
a.Value = slog.StringValue(filepath.Base(src.File) + ":" + strconv.Itoa(src.Line))
|
||||
default:
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
)
|
||||
|
||||
// AllowedLevel is a settable identifier for the minimum level a log entry
|
||||
// must be have.
|
||||
type AllowedLevel struct {
|
||||
s string
|
||||
lvl *slog.LevelVar
|
||||
}
|
||||
|
||||
func (l *AllowedLevel) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
var s string
|
||||
type plain string
|
||||
if err := unmarshal((*plain)(&s)); err != nil {
|
||||
return err
|
||||
}
|
||||
if s == "" {
|
||||
return nil
|
||||
}
|
||||
lo := &AllowedLevel{}
|
||||
if err := lo.Set(s); err != nil {
|
||||
return err
|
||||
}
|
||||
*l = *lo
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *AllowedLevel) String() string {
|
||||
return l.s
|
||||
}
|
||||
|
||||
// Set updates the value of the allowed level.
|
||||
func (l *AllowedLevel) Set(s string) error {
|
||||
if l.lvl == nil {
|
||||
l.lvl = &slog.LevelVar{}
|
||||
}
|
||||
|
||||
switch strings.ToLower(s) {
|
||||
case "debug":
|
||||
l.lvl.Set(slog.LevelDebug)
|
||||
callerAddFunc = true
|
||||
case "info":
|
||||
l.lvl.Set(slog.LevelInfo)
|
||||
callerAddFunc = false
|
||||
case "warn":
|
||||
l.lvl.Set(slog.LevelWarn)
|
||||
callerAddFunc = false
|
||||
case "error":
|
||||
l.lvl.Set(slog.LevelError)
|
||||
callerAddFunc = false
|
||||
default:
|
||||
return fmt.Errorf("unrecognized log level %s", s)
|
||||
}
|
||||
l.s = s
|
||||
return nil
|
||||
}
|
||||
|
||||
// AllowedFormat is a settable identifier for the output format that the logger can have.
|
||||
type AllowedFormat struct {
|
||||
s string
|
||||
}
|
||||
|
||||
func (f *AllowedFormat) String() string {
|
||||
return f.s
|
||||
}
|
||||
|
||||
// Set updates the value of the allowed format.
|
||||
func (f *AllowedFormat) Set(s string) error {
|
||||
switch s {
|
||||
case "logfmt", "json":
|
||||
f.s = s
|
||||
default:
|
||||
return fmt.Errorf("unrecognized log format %s", s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Config is a struct containing configurable settings for the logger
|
||||
type Config struct {
|
||||
Level *AllowedLevel
|
||||
Format *AllowedFormat
|
||||
Style LogStyle
|
||||
Writer io.Writer
|
||||
}
|
||||
|
||||
// New returns a new slog.Logger. Each logged line will be annotated
|
||||
// with a timestamp. The output always goes to stderr.
|
||||
func New(config *Config) *slog.Logger {
|
||||
if config.Level == nil {
|
||||
config.Level = &AllowedLevel{}
|
||||
_ = config.Level.Set("info")
|
||||
}
|
||||
|
||||
if config.Writer == nil {
|
||||
config.Writer = defaultWriter
|
||||
}
|
||||
|
||||
logHandlerOpts := &slog.HandlerOptions{
|
||||
Level: config.Level.lvl,
|
||||
AddSource: true,
|
||||
ReplaceAttr: defaultReplaceAttrFunc,
|
||||
}
|
||||
|
||||
if config.Style == GoKitStyle {
|
||||
logHandlerOpts.ReplaceAttr = goKitStyleReplaceAttrFunc
|
||||
}
|
||||
|
||||
if config.Format != nil && config.Format.s == "json" {
|
||||
return slog.New(slog.NewJSONHandler(config.Writer, logHandlerOpts))
|
||||
}
|
||||
return slog.New(slog.NewTextHandler(config.Writer, logHandlerOpts))
|
||||
}
|
||||
|
||||
// NewNopLogger is a convenience function to return an slog.Logger that writes
|
||||
// to io.Discard.
|
||||
func NewNopLogger() *slog.Logger {
|
||||
return slog.New(slog.NewTextHandler(io.Discard, nil))
|
||||
}
|
||||
2
vendor/github.com/shurcooL/httpfs/filter/filters.go
generated
vendored
2
vendor/github.com/shurcooL/httpfs/filter/filters.go
generated
vendored
@@ -8,7 +8,7 @@ import (
|
||||
// FilesWithExtensions returns a filter func that selects files (but not directories)
|
||||
// that have any of the given extensions. For example:
|
||||
//
|
||||
// filter.FilesWithExtensions(".go", ".html")
|
||||
// filter.FilesWithExtensions(".go", ".html")
|
||||
//
|
||||
// Would select both .go and .html files. It would not select any directories.
|
||||
func FilesWithExtensions(exts ...string) Func {
|
||||
|
||||
4
vendor/github.com/shurcooL/httpfs/vfsutil/vfsutil.go
generated
vendored
4
vendor/github.com/shurcooL/httpfs/vfsutil/vfsutil.go
generated
vendored
@@ -2,7 +2,7 @@
|
||||
package vfsutil
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
@@ -35,5 +35,5 @@ func ReadFile(fs http.FileSystem, path string) ([]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
defer rc.Close()
|
||||
return ioutil.ReadAll(rc)
|
||||
return io.ReadAll(rc)
|
||||
}
|
||||
|
||||
16
vendor/github.com/shurcooL/vfsgen/.travis.yml
generated
vendored
16
vendor/github.com/shurcooL/vfsgen/.travis.yml
generated
vendored
@@ -1,16 +0,0 @@
|
||||
sudo: false
|
||||
language: go
|
||||
go:
|
||||
- 1.x
|
||||
- master
|
||||
matrix:
|
||||
allow_failures:
|
||||
- go: master
|
||||
fast_finish: true
|
||||
install:
|
||||
- # Do nothing. This is needed to prevent default install action "go get -t -v ./..." from happening here (we want it to happen inside script step).
|
||||
script:
|
||||
- go get -t -v ./...
|
||||
- diff -n <(echo -n) <(gofmt -d -s .)
|
||||
- go vet ./...
|
||||
- go test -v -race ./...
|
||||
18
vendor/github.com/shurcooL/vfsgen/README.md
generated
vendored
18
vendor/github.com/shurcooL/vfsgen/README.md
generated
vendored
@@ -1,7 +1,7 @@
|
||||
vfsgen
|
||||
======
|
||||
|
||||
[](https://travis-ci.org/shurcooL/vfsgen) [](https://godoc.org/github.com/shurcooL/vfsgen)
|
||||
[](https://pkg.go.dev/github.com/shurcooL/vfsgen)
|
||||
|
||||
Package vfsgen takes an http.FileSystem (likely at `go generate` time) and
|
||||
generates Go code that statically implements the provided http.FileSystem.
|
||||
@@ -19,8 +19,8 @@ Features:
|
||||
Installation
|
||||
------------
|
||||
|
||||
```bash
|
||||
go get -u github.com/shurcooL/vfsgen
|
||||
```sh
|
||||
go get github.com/shurcooL/vfsgen
|
||||
```
|
||||
|
||||
Usage
|
||||
@@ -81,7 +81,7 @@ By using build tags, you can create a development mode where assets are loaded d
|
||||
For example, suppose your source filesystem is defined in a package with import path "example.com/project/data" as:
|
||||
|
||||
```Go
|
||||
// +build dev
|
||||
//go:build dev
|
||||
|
||||
package data
|
||||
|
||||
@@ -96,7 +96,7 @@ When built with the "dev" build tag, accessing `data.Assets` will read from disk
|
||||
A generate helper file assets_generate.go can be invoked via "//go:generate go run -tags=dev assets_generate.go" directive:
|
||||
|
||||
```Go
|
||||
// +build ignore
|
||||
//go:build ignore
|
||||
|
||||
package main
|
||||
|
||||
@@ -177,6 +177,7 @@ It strives to be the best in its class in terms of code quality and efficiency o
|
||||
|
||||
### Alternatives
|
||||
|
||||
- [`embed`](https://go.dev/pkg/embed) - Package embed provides access to files embedded in the running Go program.
|
||||
- [`go-bindata`](https://github.com/jteeuwen/go-bindata) - Reads from disk, generates Go code that provides access to data via a [custom API](https://github.com/jteeuwen/go-bindata#accessing-an-asset).
|
||||
- [`go-bindata-assetfs`](https://github.com/elazarl/go-bindata-assetfs) - Takes output of go-bindata and provides a wrapper that implements `http.FileSystem` interface (the same as what vfsgen outputs directly).
|
||||
- [`becky`](https://github.com/tv42/becky) - Embeds assets as string literals in Go source.
|
||||
@@ -195,6 +196,13 @@ Attribution
|
||||
|
||||
This package was originally based on the excellent work by [@jteeuwen](https://github.com/jteeuwen) on [`go-bindata`](https://github.com/jteeuwen/go-bindata) and [@elazarl](https://github.com/elazarl) on [`go-bindata-assetfs`](https://github.com/elazarl/go-bindata-assetfs).
|
||||
|
||||
Directories
|
||||
-----------
|
||||
|
||||
| Path | Synopsis |
|
||||
|------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------|
|
||||
| [cmd/vfsgendev](https://pkg.go.dev/github.com/shurcooL/vfsgen/cmd/vfsgendev) | vfsgendev is a convenience tool for using vfsgen in a common development configuration. |
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
|
||||
13
vendor/github.com/shurcooL/vfsgen/generator.go
generated
vendored
13
vendor/github.com/shurcooL/vfsgen/generator.go
generated
vendored
@@ -5,7 +5,6 @@ import (
|
||||
"compress/gzip"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
pathpkg "path"
|
||||
@@ -47,7 +46,7 @@ func Generate(input http.FileSystem, opt Options) error {
|
||||
}
|
||||
|
||||
// Write output file (all at once).
|
||||
err = ioutil.WriteFile(opt.Filename, buf.Bytes(), 0644)
|
||||
err = os.WriteFile(opt.Filename, buf.Bytes(), 0644)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -217,7 +216,7 @@ var t = template.Must(template.New("").Funcs(template.FuncMap{
|
||||
},
|
||||
}).Parse(`{{define "Header"}}// Code generated by vfsgen; DO NOT EDIT.
|
||||
|
||||
{{with .BuildTags}}// +build {{.}}
|
||||
{{with .BuildTags}}//go:build {{.}}
|
||||
|
||||
{{end}}package {{.PackageName}}
|
||||
|
||||
@@ -226,7 +225,6 @@ import (
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
pathpkg "path"
|
||||
@@ -358,7 +356,7 @@ func (f *vfsgen۰CompressedFile) Read(p []byte) (n int, err error) {
|
||||
}
|
||||
if f.grPos < f.seekPos {
|
||||
// Fast-forward.
|
||||
_, err = io.CopyN(ioutil.Discard, f.gr, f.seekPos-f.grPos)
|
||||
_, err = io.CopyN(io.Discard, f.gr, f.seekPos-f.grPos)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -386,9 +384,8 @@ func (f *vfsgen۰CompressedFile) Close() error {
|
||||
return f.gr.Close()
|
||||
}
|
||||
{{else}}
|
||||
// We already imported "compress/gzip" and "io/ioutil", but ended up not using them. Avoid unused import error.
|
||||
var _ = gzip.Reader{}
|
||||
var _ = ioutil.Discard
|
||||
// We already imported "compress/gzip" but ended up not using it. Avoid unused import error.
|
||||
var _ *gzip.Reader
|
||||
{{end}}{{if .HasFile}}
|
||||
// vfsgen۰FileInfo is a static definition of an uncompressed file (because it's not worth gzip compressing).
|
||||
type vfsgen۰FileInfo struct {
|
||||
|
||||
24
vendor/modules.txt
vendored
24
vendor/modules.txt
vendored
@@ -439,8 +439,8 @@ github.com/go-acme/lego/v4/challenge
|
||||
# github.com/go-asn1-ber/asn1-ber v1.5.7
|
||||
## explicit; go 1.13
|
||||
github.com/go-asn1-ber/asn1-ber
|
||||
# github.com/go-chi/chi/v5 v5.2.0
|
||||
## explicit; go 1.14
|
||||
# github.com/go-chi/chi/v5 v5.2.1
|
||||
## explicit; go 1.20
|
||||
github.com/go-chi/chi/v5
|
||||
github.com/go-chi/chi/v5/middleware
|
||||
# github.com/go-chi/render v1.0.3
|
||||
@@ -1194,7 +1194,7 @@ github.com/open-policy-agent/opa/v1/types
|
||||
github.com/open-policy-agent/opa/v1/util
|
||||
github.com/open-policy-agent/opa/v1/util/decoding
|
||||
github.com/open-policy-agent/opa/v1/version
|
||||
# github.com/opencloud-eu/reva/v2 v2.27.3-0.20250312134906-766c69c5d1be
|
||||
# github.com/opencloud-eu/reva/v2 v2.27.3-0.20250314084055-d2fcfe6b3445
|
||||
## explicit; go 1.24.1
|
||||
github.com/opencloud-eu/reva/v2/cmd/revad/internal/grace
|
||||
github.com/opencloud-eu/reva/v2/cmd/revad/runtime
|
||||
@@ -1629,12 +1629,12 @@ github.com/pmezard/go-difflib/difflib
|
||||
## explicit; go 1.16
|
||||
github.com/pquerna/cachecontrol
|
||||
github.com/pquerna/cachecontrol/cacheobject
|
||||
# github.com/prometheus/alertmanager v0.27.0
|
||||
## explicit; go 1.21
|
||||
# github.com/prometheus/alertmanager v0.28.1
|
||||
## explicit; go 1.22.0
|
||||
github.com/prometheus/alertmanager/asset
|
||||
github.com/prometheus/alertmanager/featurecontrol
|
||||
github.com/prometheus/alertmanager/matchers/compat
|
||||
github.com/prometheus/alertmanager/matchers/parse
|
||||
github.com/prometheus/alertmanager/matcher/compat
|
||||
github.com/prometheus/alertmanager/matcher/parse
|
||||
github.com/prometheus/alertmanager/pkg/labels
|
||||
github.com/prometheus/alertmanager/template
|
||||
github.com/prometheus/alertmanager/types
|
||||
@@ -1652,7 +1652,9 @@ github.com/prometheus/client_model/go
|
||||
# github.com/prometheus/common v0.62.0
|
||||
## explicit; go 1.21
|
||||
github.com/prometheus/common/expfmt
|
||||
github.com/prometheus/common/helpers/templates
|
||||
github.com/prometheus/common/model
|
||||
github.com/prometheus/common/promslog
|
||||
# github.com/prometheus/procfs v0.15.1
|
||||
## explicit; go 1.20
|
||||
github.com/prometheus/procfs
|
||||
@@ -1778,13 +1780,13 @@ github.com/shamaton/msgpack/v2/internal/encoding
|
||||
github.com/shamaton/msgpack/v2/internal/stream/decoding
|
||||
github.com/shamaton/msgpack/v2/internal/stream/encoding
|
||||
github.com/shamaton/msgpack/v2/time
|
||||
# github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749
|
||||
## explicit
|
||||
# github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c
|
||||
## explicit; go 1.19
|
||||
github.com/shurcooL/httpfs/filter
|
||||
github.com/shurcooL/httpfs/union
|
||||
github.com/shurcooL/httpfs/vfsutil
|
||||
# github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546
|
||||
## explicit
|
||||
# github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92
|
||||
## explicit; go 1.19
|
||||
github.com/shurcooL/vfsgen
|
||||
# github.com/sirupsen/logrus v1.9.3
|
||||
## explicit; go 1.13
|
||||
|
||||
Reference in New Issue
Block a user