Compare commits

..

28 Commits

Author SHA1 Message Date
OpenCloud Devops
25d5dab696 🎉 Release 2.0.2 (#768)
* 🎉 Release 2.0.2
2025-05-02 14:50:29 +02:00
Viktor Scharf
e0f05003ef chore: bump version v2.29.3 (#766) 2025-05-02 14:20:10 +02:00
Michael Barz
1cdd21591a fix: do not overwrite github release 2025-04-28 17:30:01 +02:00
OpenCloud Devops
e730c6ed3a 🎉 Release 2.0.1 (#640)
* 🎉 Release 2.0.1
2025-04-28 12:11:13 +02:00
Viktor Scharf
7076185c0f chore: prepare release, bump version (#731)
* chore: prepare release, bump version

* Update version.go
2025-04-28 11:25:19 +02:00
Michael Barz
87ea852a21 chore: remove docs workflows (#698) 2025-04-20 23:16:14 +02:00
Viktor Scharf
4988709fd7 fix: binary release version (#695)
Co-authored-by: Michael Barz <michael.barz@zeitgestalten.eu>
2025-04-17 15:27:52 +02:00
Viktor Scharf
f1ba964365 Merge pull request #694 from opencloud-eu/port#686
fix(decomposeds3): enable async-uploads by default (#686)
2025-04-17 14:59:08 +02:00
Michael Barz
7608ae482c fix: skip labels bot on prs from forks 2025-04-17 14:00:51 +02:00
Florian Schade
abe653ed49 fix(decomposeds3): enable async-uploads by default (#686) 2025-04-17 13:59:23 +02:00
Florian Schade
b67ce7cd34 Merge pull request #689 from opencloud-eu/port#567
Port #567
2025-04-17 11:29:54 +02:00
dependabot[bot]
3263c16652 build(deps): bump github.com/nats-io/nats.go from 1.39.1 to 1.41.0
Bumps [github.com/nats-io/nats.go](https://github.com/nats-io/nats.go) from 1.39.1 to 1.41.0.
- [Release notes](https://github.com/nats-io/nats.go/releases)
- [Commits](https://github.com/nats-io/nats.go/compare/v1.39.1...v1.41.0)

---
updated-dependencies:
- dependency-name: github.com/nats-io/nats.go
  dependency-version: 1.41.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-17 09:35:17 +02:00
Viktor Scharf
c8df6a27b6 bump reva 2.29.2 (#681) 2025-04-17 09:17:11 +02:00
Viktor Scharf
a3a5a5a047 Merge pull request #685 from opencloud-eu/addLabelBotToStableBranch
Add label bot to stable branch
2025-04-17 09:09:58 +02:00
Viktor Scharf
a80ecf0b88 Merge pull request #680 from opencloud-eu/ci/pick-release-plugin-fixes
ci: make release plugin compatible with stable branch workflow
2025-04-17 09:09:51 +02:00
Ralf Haferkamp
17604171fe ci: Allow the Type:DevOps label 2025-04-16 14:18:33 +02:00
Michael Barz
df4d427e66 feat: add labels bot (#513) 2025-04-16 14:18:12 +02:00
Viktor Scharf
c1ddc61f2b Merge pull request #683 from opencloud-eu/backPort#679
build(deps): bump github.com/nats-io/nats-server/v2
2025-04-16 14:06:12 +02:00
dependabot[bot]
fa9282bec2 build(deps): bump github.com/nats-io/nats-server/v2
Bumps [github.com/nats-io/nats-server/v2](https://github.com/nats-io/nats-server) from 2.11.0 to 2.11.1.
- [Release notes](https://github.com/nats-io/nats-server/releases)
- [Changelog](https://github.com/nats-io/nats-server/blob/main/.goreleaser.yml)
- [Commits](https://github.com/nats-io/nats-server/compare/v2.11.0...v2.11.1)

---
updated-dependencies:
- dependency-name: github.com/nats-io/nats-server/v2
  dependency-version: 2.11.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-16 13:30:12 +02:00
Jannik Stehle
9759a2dee2 ci: make release plugin compatible with stable branch workflow
Introduces the 2 configs `getLatestTag` and `useLatestRelease` to make the `ready-release-go` plugin fully compatible with our stable branch workflow.
2025-04-16 09:51:51 +02:00
Florian Schade
1bea4b7471 Merge pull request #620 from fschade/backport-antivirus-max-size-fix
fix(antivirus | backport): introduce a default max scan size for the full example deployment
2025-04-10 14:48:00 +02:00
Viktor Scharf
f266857cf1 Merge pull request #638 from opencloud-eu/chore/bump-web-to-v2.1.1
[full-ci] chore(web): bump web to v2.1.1
2025-04-10 11:22:47 +02:00
Jannik Stehle
d15c961c31 chore: bump web to v2.1.1 2025-04-10 09:34:04 +02:00
Florian Schade
9238639753 fix(antivirus): introduce a default max scan size for the full example deployment 2025-04-08 17:37:51 +02:00
Michael Barz
0718947b0c Add correct CI badge README.md 2025-04-04 21:58:49 +02:00
Michael Barz
2fc33db3aa test: enable exclude condition again 2025-04-04 17:32:14 +02:00
Michael Barz
05f0a8dc96 fix: push Readme only on main branch 2025-04-04 17:19:59 +02:00
Michael Barz
8697e6a4c8 feat: use correct triggers and base branch 2025-04-04 17:11:07 +02:00
208 changed files with 3507 additions and 11984 deletions

View File

@@ -4,6 +4,8 @@ on:
types: [opened, labeled, unlabeled, synchronize]
jobs:
label:
# Only run if PR is not from a fork
if: github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
permissions:
issues: write

View File

@@ -18,20 +18,21 @@ SOURCES ?= $(shell find . -name "*.go" -type f -not -path "./node_modules/*")
TAGS ?=
ifndef OUTPUT
ifneq ($(CI_COMMIT_TAG),)
OUTPUT ?= $(subst v,,$(CI_COMMIT_TAG))
ifneq ($(DRONE_TAG),)
OUTPUT ?= $(subst v,,$(DRONE_TAG))
else
OUTPUT ?= testing
endif
endif
ifeq ($(VERSION), daily)
STRING ?= $(shell git rev-parse --short HEAD)
else ifeq ($(VERSION),)
STRING ?= $(shell git rev-parse --short HEAD)
ifndef VERSION
ifneq ($(DRONE_TAG),)
VERSION ?= $(subst v,,$(DRONE_TAG))
else
STRING ?= $(shell git rev-parse --short HEAD)
endif
endif
ifndef DATE
DATE := $(shell date -u '+%Y%m%d')
endif

View File

@@ -1,3 +1,3 @@
# The test runner source for UI tests
WEB_COMMITID=25629bf0d846051ec0ed6f56ddbeb1a4de6f9ba0
WEB_BRANCH=main
WEB_COMMITID=59e329cc5fe288cf247cc5272547a77ac59cc000
WEB_BRANCH=stable-2.1

View File

@@ -12,6 +12,9 @@ PRODUCTION_RELEASE_TAGS = ["2.0", "3.0"]
repo_slug = "opencloud-eu/opencloud"
docker_repo_slug = "opencloudeu/opencloud"
# Active base branch for this code stream
branch = "stable-2.0"
# images
ALPINE_GIT = "alpine/git:latest"
APACHE_TIKA = "apache/tika:2.8.0.0"
@@ -416,9 +419,10 @@ def main(ctx):
none
"""
pipelines = []
build_release_helpers = \
readyReleaseGo() + \
docs()
readyReleaseGo()
build_release_helpers.append(
pipelineDependsOn(
@@ -429,8 +433,8 @@ def main(ctx):
test_pipelines = \
codestyle(ctx) + \
checkGherkinLint() + \
checkTestSuitesInExpectedFailures() + \
checkGherkinLint(ctx) + \
checkTestSuitesInExpectedFailures(ctx) + \
buildWebCache(ctx) + \
getGoBinForTesting(ctx) + \
buildOpencloudBinaryForTesting(ctx) + \
@@ -472,7 +476,7 @@ def main(ctx):
),
)
pipelineSanityChecks(pipelines)
pipelineSanityChecks(ctx, pipelines)
return pipelines
def cachePipeline(name, steps):
@@ -680,7 +684,7 @@ def testOpencloud(ctx):
"when": [
{
"event": ["push", "manual"],
"branch": "main",
"branch": ["main", "stable-*"],
},
{
"event": "pull_request",
@@ -711,7 +715,7 @@ def scanOpencloud(ctx):
"when": [
{
"event": ["push", "manual"],
"branch": "main",
"branch": ["main", "stable-*"],
},
{
"event": "pull_request",
@@ -734,7 +738,7 @@ def buildOpencloudBinaryForTesting(ctx):
"when": [
{
"event": ["push", "manual"],
"branch": "main",
"branch": ["main", "stable-*"],
},
{
"event": "pull_request",
@@ -770,7 +774,7 @@ def vendorbinCodesniffer(phpVersion):
],
}]
def checkTestSuitesInExpectedFailures():
def checkTestSuitesInExpectedFailures(ctx):
return [{
"name": "check-suites-in-expected-failures",
"steps": [
@@ -789,7 +793,7 @@ def checkTestSuitesInExpectedFailures():
],
}]
def checkGherkinLint():
def checkGherkinLint(ctx):
return [{
"name": "check-gherkin-standard",
"steps": [
@@ -869,7 +873,7 @@ def codestyle(ctx):
"when": [
{
"event": ["push", "manual"],
"branch": "main",
"branch": ["main", "stable-*"],
},
{
"event": "pull_request",
@@ -930,7 +934,7 @@ def localApiTestPipeline(ctx):
(opencloudServer(storage, params["accounts_hash_difficulty"], deploy_type = "federation", extra_server_environment = params["extraServerEnvironment"]) if params["federationServer"] else []) +
((wopiCollaborationService("fakeoffice") + wopiCollaborationService("collabora") + wopiCollaborationService("onlyoffice")) if params["collaborationServiceNeeded"] else []) +
(openCloudHealthCheck("wopi", ["wopi-collabora:9304", "wopi-onlyoffice:9304", "wopi-fakeoffice:9304"]) if params["collaborationServiceNeeded"] else []) +
localApiTests(name, params["suites"], storage, params["extraEnvironment"], run_with_remote_php) +
localApiTests(ctx, name, params["suites"], storage, params["extraEnvironment"], run_with_remote_php) +
logRequests(),
"services": (emailService() if params["emailNeeded"] else []) +
(clamavService() if params["antivirusNeeded"] else []) +
@@ -939,7 +943,7 @@ def localApiTestPipeline(ctx):
"when": [
{
"event": ["push", "manual"],
"branch": "main",
"branch": ["main", "stable-*"],
},
{
"event": "pull_request",
@@ -952,9 +956,9 @@ def localApiTestPipeline(ctx):
pipelines.append(pipeline)
return pipelines
def localApiTests(name, suites, storage = "decomposed", extra_environment = {}, with_remote_php = False):
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-decomposed-storage.md" % test_dir
expected_failures_file = "%s/expected-failures-localAPI-on-decomposed-storage.md" % (test_dir)
environment = {
"TEST_SERVER_URL": OC_URL,
@@ -988,7 +992,7 @@ def cs3ApiTests(ctx, storage, accounts_hash_difficulty = 4):
return {
"name": "cs3ApiTests-%s" % storage,
"steps": restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]) +
opencloudServer(storage, accounts_hash_difficulty, deploy_type = "cs3api_validator") +
opencloudServer(storage, accounts_hash_difficulty, [], [], "cs3api_validator") +
[
{
"name": "cs3ApiTests",
@@ -1005,7 +1009,7 @@ def cs3ApiTests(ctx, storage, accounts_hash_difficulty = 4):
"when": [
{
"event": ["push", "manual"],
"branch": "main",
"branch": ["main", "stable-*"],
},
{
"event": "pull_request",
@@ -1034,6 +1038,7 @@ def wopiValidatorTests(ctx, storage, wopiServerType, accounts_hash_difficulty =
]
validatorTests = []
wopiServer = []
extra_server_environment = {}
if wopiServerType == "cs3":
@@ -1121,7 +1126,7 @@ def wopiValidatorTests(ctx, storage, wopiServerType, accounts_hash_difficulty =
"when": [
{
"event": ["push", "manual"],
"branch": "main",
"branch": ["main", "stable-*"],
},
{
"event": "pull_request",
@@ -1175,7 +1180,7 @@ def coreApiTests(ctx, part_number = 1, number_of_parts = 1, with_remote_php = Fa
"when": [
{
"event": ["push", "manual"],
"branch": "main",
"branch": ["main", "stable-*"],
},
{
"event": "pull_request",
@@ -1201,7 +1206,7 @@ def apiTests(ctx):
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):
if (not debugPartsEnabled or (debugPartsEnabled and runPart in debugParts)):
pipelines.append(coreApiTests(ctx, runPart, config["apiTests"]["numberOfParts"], run_with_remote_php))
return pipelines
@@ -1225,7 +1230,7 @@ def e2eTestPipeline(ctx):
e2e_trigger = [
{
"event": ["push", "manual"],
"branch": "main",
"branch": ["main", "stable-*"],
},
{
"event": "pull_request",
@@ -1241,10 +1246,10 @@ def e2eTestPipeline(ctx):
pipelines = []
if "skip-e2e" in ctx.build.title.lower():
if ("skip-e2e" in ctx.build.title.lower()):
return pipelines
if ctx.build.event == "tag":
if (ctx.build.event == "tag"):
return pipelines
storage = "posix"
@@ -1334,7 +1339,7 @@ def multiServiceE2ePipeline(ctx):
e2e_trigger = [
{
"event": ["push", "manual"],
"branch": "main",
"branch": ["main", "stable-*"],
},
{
"event": "pull_request",
@@ -1344,11 +1349,11 @@ def multiServiceE2ePipeline(ctx):
},
]
if "skip-e2e" in ctx.build.title.lower():
if ("skip-e2e" in ctx.build.title.lower()):
return pipelines
# run this pipeline only for cron jobs and full-ci PRs
if not "full-ci" in ctx.build.title.lower() and ctx.build.event != "cron":
if (not "full-ci" in ctx.build.title.lower() and ctx.build.event != "cron"):
return pipelines
storage = "posix"
@@ -1452,7 +1457,7 @@ def multiServiceE2ePipeline(ctx):
})
return pipelines
def uploadTracingResult():
def uploadTracingResult(ctx):
return [{
"name": "upload-tracing-result",
"image": PLUGINS_S3,
@@ -1546,7 +1551,7 @@ def dockerReleases(ctx):
def dockerRelease(ctx, repo, build_type):
build_args = [
"REVISION=%s" % ctx.build.commit,
"REVISION=%s" % (ctx.build.commit),
"VERSION=%s" % (ctx.build.ref.replace("refs/tags/", "") if ctx.build.event == "tag" else "daily"),
]
@@ -1625,10 +1630,6 @@ def dockerRelease(ctx, repo, build_type):
],
},
"when": [
{
"event": ["push", "manual"],
"branch": "main",
},
{
"event": "tag",
},
@@ -1639,7 +1640,7 @@ def dockerRelease(ctx, repo, build_type):
"when": [
{
"event": ["push", "manual"],
"branch": "main",
"branch": ["main", "stable-*"],
},
{
"event": "pull_request",
@@ -1670,7 +1671,15 @@ def binaryRelease(ctx, arch, depends_on = []):
{
"name": "build",
"image": OC_CI_GOLANG,
"environment": CI_HTTP_PROXY_ENV,
"environment": {
"VERSION": (ctx.build.ref.replace("refs/tags/", "") if ctx.build.event == "tag" else "daily"),
"HTTP_PROXY": {
"from_secret": "ci_http_proxy",
},
"HTTPS_PROXY": {
"from_secret": "ci_http_proxy",
},
},
"commands": [
"make -C opencloud release-%s" % arch,
],
@@ -1683,10 +1692,6 @@ def binaryRelease(ctx, arch, depends_on = []):
"make -C opencloud release-finish",
],
"when": [
{
"event": ["push", "manual"],
"branch": "main",
},
{
"event": "tag",
},
@@ -1716,7 +1721,7 @@ def binaryRelease(ctx, arch, depends_on = []):
"when": [
{
"event": ["push", "manual"],
"branch": "main",
"branch": ["main", "stable-*"],
},
{
"event": "pull_request",
@@ -1794,7 +1799,7 @@ def licenseCheck(ctx):
"when": [
{
"event": ["push", "manual"],
"branch": "main",
"branch": ["main", "stable-*"],
},
{
"event": "pull_request",
@@ -1819,13 +1824,14 @@ def readyReleaseGo():
"forge_token": {
"from_secret": "github_token",
},
"release_branch": branch,
},
},
],
"when": [
{
"event": ["push", "manual"],
"branch": "main",
"branch": ["main", "stable-*"],
},
],
}]
@@ -1845,7 +1851,7 @@ def releaseDockerReadme(repo, build_type):
"from_secret": "docker_password",
},
"PUSHRM_TARGET": repo,
"PUSHRM_SHORT": "Docker images for %s" % repo,
"PUSHRM_SHORT": "Docker images for %s" % (repo),
"PUSHRM_FILE": "README.md",
},
},
@@ -1867,45 +1873,14 @@ def releaseDockerReadme(repo, build_type):
"event": ["push", "manual"],
"branch": "main",
},
{
"event": "tag",
},
],
}
def docs():
return [
{
"name": "dev-docs",
"steps": [
{
"name": "devdocs",
"image": "codeberg.org/xfix/plugin-codeberg-pages-deploy:1",
"settings": {
"folder": "docs",
"branch": "docs",
"git_config_email": "${CI_COMMIT_AUTHOR_EMAIL}",
"git_config_name": "${CI_COMMIT_AUTHOR}",
"ssh_key": {
"from_secret": "ssh_key",
},
},
},
],
"when": [
{
"event": "push",
"branch": "main",
},
],
},
]
def makeNodeGenerate(module):
if module == "":
make = "make"
else:
make = "make -C %s" % module
make = "make -C %s" % (module)
return [
{
"name": "generate nodejs",
@@ -1915,7 +1890,7 @@ def makeNodeGenerate(module):
},
"commands": [
"pnpm config set store-dir ./.pnpm-store",
"for i in $(seq 3); do %s node-generate-prod && break || sleep 1; done" % make,
"for i in $(seq 3); do %s node-generate-prod && break || sleep 1; done" % (make),
],
},
]
@@ -1924,13 +1899,13 @@ def makeGoGenerate(module):
if module == "":
make = "make"
else:
make = "make -C %s" % module
make = "make -C %s" % (module)
return [
{
"name": "generate go",
"image": OC_CI_GOLANG,
"commands": [
"for i in $(seq 3); do %s go-generate && break || sleep 1; done" % make,
"for i in $(seq 3); do %s go-generate && break || sleep 1; done" % (make),
],
"environment": CI_HTTP_PROXY_ENV,
},
@@ -1960,7 +1935,7 @@ def notify(ctx):
"when": [
{
"event": ["push", "manual"],
"branch": ["main", "release-*"],
"branch": ["main", "stable-*", "release-*"],
},
{
"event": "tag",
@@ -1969,13 +1944,13 @@ def notify(ctx):
"runs_on": status,
}
def opencloudServer(storage = "decomposed", accounts_hash_difficulty = 4, depends_on = [], deploy_type = "", extra_server_environment = {}, with_wrapper = False, tika_enabled = False):
def opencloudServer(storage = "decomposed", accounts_hash_difficulty = 4, volumes = [], depends_on = [], deploy_type = "", extra_server_environment = {}, with_wrapper = False, tika_enabled = False):
user = "0:0"
container_name = OC_SERVER_NAME
environment = {
"OC_URL": OC_URL,
"OC_CONFIG_DIR": "/root/.opencloud/config", # needed for checking config later
"STORAGE_USERS_DRIVER": "%s" % storage,
"STORAGE_USERS_DRIVER": "%s" % (storage),
"PROXY_ENABLE_BASIC_AUTH": True,
"WEB_UI_CONFIG_FILE": "%s/%s" % (dirs["base"], dirs["opencloudConfig"]),
"OC_LOG_LEVEL": "error",
@@ -2065,7 +2040,7 @@ def opencloudServer(storage = "decomposed", accounts_hash_difficulty = 4, depend
# That will allow OpenCloud to use whatever its built-in default is.
# Otherwise pass in a value from 4 to about 11 or 12 (default 4, for making regular tests fast)
# The high values cause lots of CPU to be used when hashing passwords, and really slow down the tests.
if accounts_hash_difficulty != "default":
if (accounts_hash_difficulty != "default"):
environment["ACCOUNTS_HASH_DIFFICULTY"] = accounts_hash_difficulty
for item in extra_server_environment:
@@ -2078,7 +2053,7 @@ def opencloudServer(storage = "decomposed", accounts_hash_difficulty = 4, depend
]
wait_for_opencloud = {
"name": "wait-for-%s" % container_name,
"name": "wait-for-%s" % (container_name),
"image": OC_CI_ALPINE,
"commands": [
# wait for opencloud-server to be ready (5 minutes)
@@ -2102,7 +2077,7 @@ def opencloudServer(storage = "decomposed", accounts_hash_difficulty = 4, depend
"%s init --insecure true" % dirs["opencloudBin"],
"cat $OC_CONFIG_DIR/opencloud.yaml",
"cp tests/config/woodpecker/app-registry.yaml $OC_CONFIG_DIR/app-registry.yaml",
] + wrapper_commands,
] + (wrapper_commands),
}
steps = [
@@ -2203,6 +2178,8 @@ def skipIfUnchanged(ctx, type):
skip = base + unit + acceptance
elif type == "cache":
skip = base
else:
return []
return skip
@@ -2234,13 +2211,13 @@ def example_deploys(ctx):
deploys = []
for config in configs:
deploys.append(deploy(config, rebuild))
deploys.append(deploy(ctx, config, rebuild))
return deploys
def deploy(config, rebuild):
def deploy(ctx, config, rebuild):
return {
"name": "deploy_%s" % config,
"name": "deploy_%s" % (config),
"steps": [
{
"name": "clone continuous deployment playbook",
@@ -2255,7 +2232,7 @@ def deploy(config, rebuild):
"image": OC_CI_DRONE_ANSIBLE,
"failure": "ignore",
"environment": {
"CONTINUOUS_DEPLOY_SERVERS_CONFIG": "../%s" % config,
"CONTINUOUS_DEPLOY_SERVERS_CONFIG": "../%s" % (config),
"REBUILD": rebuild,
"HCLOUD_API_TOKEN": {
"from_secret": "hcloud_api_token",
@@ -2345,7 +2322,7 @@ def genericCache(name, action, mounts, cache_path):
"secret_key": {
"from_secret": "cache_s3_secret_key",
},
"filename": "%s.tar" % name,
"filename": "%s.tar" % (name),
"path": cache_path,
"fallback_path": cache_path,
},
@@ -2378,7 +2355,7 @@ def genericCachePurge(flush_path):
"when": [
{
"event": ["push", "manual"],
"branch": "main",
"branch": ["main", "stable-*"],
},
{
"event": "pull_request",
@@ -2390,7 +2367,7 @@ def genericCachePurge(flush_path):
def genericBuildArtifactCache(ctx, name, action, path):
if action == "rebuild" or action == "restore":
cache_path = "%s/%s/%s" % ("cache", repo_slug, ctx.build.commit + "-${CI_PIPELINE_NUMBER}")
name = "%s_build_artifact_cache" % name
name = "%s_build_artifact_cache" % (name)
return genericCache(name, action, [path], cache_path)
if action == "purge":
@@ -2407,13 +2384,14 @@ def rebuildBuildArtifactCache(ctx, name, path):
def purgeBuildArtifactCache(ctx):
return genericBuildArtifactCache(ctx, "", "purge", [])
def pipelineSanityChecks(pipelines):
def pipelineSanityChecks(ctx, pipelines):
"""pipelineSanityChecks helps the CI developers to find errors before running it
These sanity checks are only executed on when converting starlark to yaml.
Error outputs are only visible when the conversion is done with the woodpecker cli.
Args:
ctx: woodpecker passes a context with information which the pipeline can be adapted to
pipelines: pipelines to be checked, normally you should run this on the return value of main()
Returns:
@@ -2425,7 +2403,7 @@ def pipelineSanityChecks(pipelines):
for pipeline in pipelines:
pipeline_name = pipeline["name"]
if len(pipeline_name) > max_name_length:
print("Error: pipeline name %s is longer than 50 characters" % pipeline_name)
print("Error: pipeline name %s is longer than 50 characters" % (pipeline_name))
for step in pipeline["steps"]:
step_name = step["name"]
@@ -2476,7 +2454,7 @@ def pipelineSanityChecks(pipelines):
def litmus(ctx, storage):
pipelines = []
if not config["litmus"]:
if (config["litmus"] == False):
return pipelines
environment = {
@@ -2563,7 +2541,7 @@ def litmus(ctx, storage):
"when": [
{
"event": ["push", "manual"],
"branch": "main",
"branch": ["main", "stable-*"],
},
{
"event": "pull_request",

View File

@@ -1,16 +0,0 @@
---
when:
- event: ["push", "manual"]
branch: main
steps:
- name: devdocs
image: codeberg.org/xfix/plugin-codeberg-pages-deploy:1
settings:
folder: docs
branch: docs
git_config_email: ${CI_COMMIT_AUTHOR_EMAIL}
git_config_name: ${CI_COMMIT_AUTHOR}
ssh_key:
from_secret: ssh_key

View File

@@ -1,45 +1,33 @@
# Changelog
## [2.1.0](https://github.com/opencloud-eu/opencloud/releases/tag/v2.1.0) - 2025-04-07
## [2.0.2](https://github.com/opencloud-eu/opencloud/releases/tag/v2.0.2) - 2025-05-02
### ❤️ Thanks to all contributors! ❤️
@AlexAndBear, @JammingBen, @ScharfViktor, @aduffeck, @butonic, @fschade, @individual-it, @kulmann, @micbar, @michaelstingl, @rhafer
@ScharfViktor
### 🐛 Bug Fixes
- feat(antivirus): add partial scanning mode [[#559](https://github.com/opencloud-eu/opencloud/pull/559)]
- Simplify item-trashed SSEs. Also fixes it for coll. posix fs. [[#565](https://github.com/opencloud-eu/opencloud/pull/565)]
- fix(opencloud_full): add missing SMTP env vars [[#563](https://github.com/opencloud-eu/opencloud/pull/563)]
- fix: full deployment tika description is wrong [[#553](https://github.com/opencloud-eu/opencloud/pull/553)]
- fix: traefik credentials [[#555](https://github.com/opencloud-eu/opencloud/pull/555)]
- Enable scan/watch in the storageprovider only [[#546](https://github.com/opencloud-eu/opencloud/pull/546)]
- fix: typo in dev docs [[#540](https://github.com/opencloud-eu/opencloud/pull/540)]
- Abort when the space root has already been created [[#766](https://github.com/opencloud-eu/opencloud/pull/766)]
### 📈 Enhancement
## [2.0.1](https://github.com/opencloud-eu/opencloud/releases/tag/v2.0.1) - 2025-04-28
- [full-ci] reva bump 2.31.0 [[#599](https://github.com/opencloud-eu/opencloud/pull/599)]
- feat: support svg as icon [[#538](https://github.com/opencloud-eu/opencloud/pull/538)]
- feat: change theme.json primary color [[#536](https://github.com/opencloud-eu/opencloud/pull/536)]
- graph: reduce memory allocations [[#494](https://github.com/opencloud-eu/opencloud/pull/494)]
### ❤️ Thanks to all contributors! ❤️
### ✅ Tests
@JammingBen, @ScharfViktor, @fschade, @micbar
- [full-ci] fix expected spanish string in test [[#596](https://github.com/opencloud-eu/opencloud/pull/596)]
- Revert "Disable the 'exclude' patterns on the path conditional for now" [[#561](https://github.com/opencloud-eu/opencloud/pull/561)]
### 🐛 Bug Fixes
- fix(decomposeds3): enable async-uploads by default (#686) [[#694](https://github.com/opencloud-eu/opencloud/pull/694)]
- fix(antivirus | backport): introduce a default max scan size for the full example deployment [[#620](https://github.com/opencloud-eu/opencloud/pull/620)]
- [full-ci] chore(web): bump web to v2.1.1 [[#638](https://github.com/opencloud-eu/opencloud/pull/638)]
### 📦️ Dependencies
- build(deps): bump github.com/go-playground/validator/v10 from 10.25.0 to 10.26.0 [[#571](https://github.com/opencloud-eu/opencloud/pull/571)]
- build(deps): bump github.com/nats-io/nats.go from 1.39.1 to 1.41.0 [[#567](https://github.com/opencloud-eu/opencloud/pull/567)]
- [full-ci] chore(web): bump web to v2.2.0 [[#570](https://github.com/opencloud-eu/opencloud/pull/570)]
- build(deps): bump github.com/onsi/gomega from 1.36.3 to 1.37.0 [[#566](https://github.com/opencloud-eu/opencloud/pull/566)]
- build(deps): bump golang.org/x/net from 0.37.0 to 0.38.0 [[#557](https://github.com/opencloud-eu/opencloud/pull/557)]
- build(deps-dev): bump eslint-plugin-jsx-a11y from 6.9.0 to 6.10.2 in /services/idp [[#542](https://github.com/opencloud-eu/opencloud/pull/542)]
- build(deps): bump web-vitals from 3.5.2 to 4.2.4 in /services/idp [[#541](https://github.com/opencloud-eu/opencloud/pull/541)]
- build(deps): bump github.com/open-policy-agent/opa from 1.2.0 to 1.3.0 [[#508](https://github.com/opencloud-eu/opencloud/pull/508)]
- build(deps): bump github.com/urfave/cli/v2 from 2.27.5 to 2.27.6 [[#509](https://github.com/opencloud-eu/opencloud/pull/509)]
- fix keycloak example #465 [[#535](https://github.com/opencloud-eu/opencloud/pull/535)]
- chore: prepare release, bump version [[#731](https://github.com/opencloud-eu/opencloud/pull/731)]
- Port #567 [[#689](https://github.com/opencloud-eu/opencloud/pull/689)]
- chore: bump reva to v2.29.2 [[#681](https://github.com/opencloud-eu/opencloud/pull/681)]
- build(deps): bump github.com/nats-io/nats-server/v2 [[#683](https://github.com/opencloud-eu/opencloud/pull/683)]
## [2.0.0](https://github.com/opencloud-eu/opencloud/releases/tag/v2.0.0) - 2025-03-26

View File

@@ -1,6 +1,6 @@
![OpenCloud logo](https://raw.githubusercontent.com/opencloud-eu/opencloud/refs/heads/main/opencloud_logo.png)
[![status-badge](https://ci.opencloud.eu/api/badges/3/status.svg)](https://ci.opencloud.eu/repos/3)
[![status-badge](https://ci.opencloud.eu/api/badges/3/status.svg?branch=stable-2.0)](https://ci.opencloud.eu/repos/3/branches/stable-2.0)
[![Matrix](https://img.shields.io/matrix/opencloud%3Amatrix.org?logo=matrix)](https://app.element.io/#/room/#opencloud:matrix.org)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

View File

@@ -31,9 +31,9 @@ to download. If not set, there is a reasonable default.
Call
```
OC_VERSION="2.0.0" ./install.sh
OC_VERSION="1.0.0" ./install.sh
```
to install the OpenCloud version 2.0.0
to install the OpenCloud version 1.0.0
There is also a hosted version of this script that makes it even
easier:

View File

@@ -37,7 +37,7 @@ function backup_file () {
# URL pattern of the download file
# https://github.com/opencloud-eu/opencloud/releases/download/v1.0.0/opencloud-1.0.0-linux-amd64
dlversion="${OC_VERSION:-2.0.0}"
dlversion="${OC_VERSION:-1.1.0}"
dlurl="https://github.com/opencloud-eu/opencloud/releases/download/v${dlversion}/"
sandbox="opencloud-sandbox-${dlversion}"

View File

@@ -17,9 +17,7 @@ TRAEFIK_DASHBOARD=
# Defaults to "traefik.opencloud.test"
TRAEFIK_DOMAIN=
# Basic authentication for the traefik dashboard.
# Defaults to user "admin" and password "admin" (written as: "admin:$2y$05$KDHu3xq92SPaO3G8Ybkc7edd51pPLJcG1nWk3lmlrIdANQ/B6r5pq").
# To create user:password pair, it's possible to use this command:
# echo $(htpasswd -nB user) | sed -e s/\\$/\\$\\$/g
# Defaults to user "admin" and password "admin" (written as: "admin:admin").
TRAEFIK_BASIC_AUTH_USERS=
# Email address for obtaining LetsEncrypt certificates.
# Needs only be changed if this is a public facing server.
@@ -100,7 +98,7 @@ MINIO_DOMAIN=
# Note: the leading colon is required to enable the service.
#DECOMPOSED=:decomposed.yml
# Define SMTP settings if you would like to send OpenCloud email notifications.
# Define SMPT settings if you would like to send OpenCloud email notifications.
#
# NOTE: when configuring Inbucket, these settings have no effect, see inbucket.yml for details.
# SMTP host to connect to.
@@ -116,8 +114,6 @@ SMTP_USERNAME=
SMTP_PASSWORD=
# Authentication method for the SMTP communication.
SMTP_AUTHENTICATION=
# Encryption method for the SMTP communication. Possible values are 'starttls', 'ssltls' and 'none'
SMTP_TRANSPORT_ENCRYPTION=
# Allow insecure connections to the SMTP server. Defaults to false.
SMTP_INSECURE=
@@ -161,7 +157,7 @@ COMPANION_ONEDRIVE_SECRET=
## Default Enabled Services ##
### Apache Tika Content Analysis Toolkit ###
# Tika (search) is disabled by default due to performance reasons.
# Tika (search) is enabled by default, comment if not required.
# Note: the leading colon is required to enable the service.
#TIKA=:tika.yml
# Set the desired docker image tag or digest.
@@ -218,9 +214,6 @@ COLLABORA_SSL_VERIFICATION=false
# Usable common abbreviations: [KB, KiB, MB, MiB, GB, GiB, TB, TiB, PB, PiB, EB, EiB], example: 2GB.
# Defaults to "100MB"
#ANTIVIRUS_MAX_SCAN_SIZE=
# Usable modes: partial, skip.
# Defaults to "partial"
#ANTIVIRUS_MAX_SCAN_SIZE_MODE=
# Image version of the ClamAV container.
# Defaults to "latest"
CLAMAV_DOCKER_TAG=
@@ -248,20 +241,8 @@ INBUCKET_DOMAIN=
# Path separator for supplemental compose files specified in COMPOSE_FILE.
COMPOSE_PATH_SEPARATOR=:
### Keycloak Settings ###
# Note: the leading colon is required to enable the service.
#KEYCLOAK=:keycloak.yml
# Domain for Keycloak. Defaults to "keycloak.opencloud.test".
KEYCLOAK_DOMAIN=
# Realm which to be used with OpenCloud. Defaults to "OpenCloud"
KEYCLOAK_REALM=
# Admin user login name. Defaults to "admin"
KEYCLOAK_ADMIN_USER=
# Admin user login password. Defaults to "admin"
KEYCLOAK_ADMIN_PASSWORD=
## IMPORTANT ##
# This MUST be the last line as it assembles the supplemental compose files to be used.
# ALL supplemental configs must be added here, whether commented or not.
# Each var must either be empty or contain :path/file.yml
COMPOSE_FILE=docker-compose.yml${OPENCLOUD:-}${TIKA:-}${DECOMPOSEDS3:-}${DECOMPOSEDS3_MINIO:-}${DECOMPOSED:-}${COLLABORA:-}${MONITORING:-}${IMPORTER:-}${CLAMAV:-}${ONLYOFFICE:-}${INBUCKET:-}${EXTENSIONS:-}${UNZIP:-}${DRAWIO:-}${JSONVIEWER:-}${PROGRESSBARS:-}${EXTERNALSITES:-}${KEYCLOAK:-}
COMPOSE_FILE=docker-compose.yml${OPENCLOUD:-}${TIKA:-}${DECOMPOSEDS3:-}${DECOMPOSEDS3_MINIO:-}${DECOMPOSED:-}${COLLABORA:-}${MONITORING:-}${IMPORTER:-}${CLAMAV:-}${ONLYOFFICE:-}${INBUCKET:-}${EXTENSIONS:-}${UNZIP:-}${DRAWIO:-}${JSONVIEWER:-}${PROGRESSBARS:-}${EXTERNALSITES:-}

View File

@@ -4,7 +4,6 @@ services:
environment:
ANTIVIRUS_SCANNER_TYPE: "clamav"
ANTIVIRUS_CLAMAV_SOCKET: "/var/run/clamav/clamd.sock"
ANTIVIRUS_MAX_SCAN_SIZE_MODE: ${ANTIVIRUS_MAX_SCAN_SIZE_MODE:-partial}
ANTIVIRUS_MAX_SCAN_SIZE: ${ANTIVIRUS_MAX_SCAN_SIZE:-100MB}
# the antivirus service needs manual startup, see .env and opencloud.yaml for START_ADDITIONAL_SERVICES
# configure the antivirus service

View File

@@ -1,63 +0,0 @@
{
"clientId": "OpenCloudAndroid",
"name": "OpenCloud Android App",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [
"oc://android.opencloud.eu"
],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": true,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": false,
"protocol": "openid-connect",
"attributes": {
"saml.assertion.signature": "false",
"saml.force.post.binding": "false",
"saml.multivalued.roles": "false",
"saml.encrypt": "false",
"post.logout.redirect.uris": "oc://android.opencloud.eu",
"backchannel.logout.revoke.offline.tokens": "false",
"saml.server.signature": "false",
"saml.server.signature.keyinfo.ext": "false",
"exclude.session.state.from.auth.response": "false",
"backchannel.logout.session.required": "true",
"client_credentials.use_refresh_token": "false",
"saml_force_name_id_format": "false",
"saml.client.signature": "false",
"tls.client.certificate.bound.access.tokens": "false",
"saml.authnstatement": "false",
"display.on.consent.screen": "false",
"saml.onetimeuse.condition": "false"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [
"web-origins",
"profile",
"roles",
"groups",
"basic",
"email"
],
"optionalClientScopes": [
"address",
"phone",
"offline_access",
"microprofile-jwt"
],
"access": {
"view": true,
"configure": true,
"manage": true
}
}

View File

@@ -1,64 +0,0 @@
{
"clientId": "OpenCloudDesktop",
"name": "OpenCloud Desktop Client",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [
"http://127.0.0.1",
"http://localhost"
],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": true,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": false,
"protocol": "openid-connect",
"attributes": {
"saml.assertion.signature": "false",
"saml.force.post.binding": "false",
"saml.multivalued.roles": "false",
"saml.encrypt": "false",
"post.logout.redirect.uris": "+",
"backchannel.logout.revoke.offline.tokens": "false",
"saml.server.signature": "false",
"saml.server.signature.keyinfo.ext": "false",
"exclude.session.state.from.auth.response": "false",
"backchannel.logout.session.required": "true",
"client_credentials.use_refresh_token": "false",
"saml_force_name_id_format": "false",
"saml.client.signature": "false",
"tls.client.certificate.bound.access.tokens": "false",
"saml.authnstatement": "false",
"display.on.consent.screen": "false",
"saml.onetimeuse.condition": "false"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [
"web-origins",
"profile",
"roles",
"groups",
"basic",
"email"
],
"optionalClientScopes": [
"address",
"phone",
"offline_access",
"microprofile-jwt"
],
"access": {
"view": true,
"configure": true,
"manage": true
}
}

View File

@@ -1,63 +0,0 @@
{
"clientId": "OpenCloudIOS",
"name": "OpenCloud iOS App",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [
"oc://ios.opencloud.eu"
],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": true,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": false,
"protocol": "openid-connect",
"attributes": {
"saml.assertion.signature": "false",
"saml.force.post.binding": "false",
"saml.multivalued.roles": "false",
"saml.encrypt": "false",
"post.logout.redirect.uris": "oc://ios.opencloud.eu",
"backchannel.logout.revoke.offline.tokens": "false",
"saml.server.signature": "false",
"saml.server.signature.keyinfo.ext": "false",
"exclude.session.state.from.auth.response": "false",
"backchannel.logout.session.required": "true",
"client_credentials.use_refresh_token": "false",
"saml_force_name_id_format": "false",
"saml.client.signature": "false",
"tls.client.certificate.bound.access.tokens": "false",
"saml.authnstatement": "false",
"display.on.consent.screen": "false",
"saml.onetimeuse.condition": "false"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [
"web-origins",
"profile",
"roles",
"groups",
"basic",
"email"
],
"optionalClientScopes": [
"address",
"phone",
"offline_access",
"microprofile-jwt"
],
"access": {
"view": true,
"configure": true,
"manage": true
}
}

View File

@@ -1,66 +0,0 @@
{
"clientId": "Cyberduck",
"name": "Cyberduck",
"description": "File transfer utility client",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [
"x-cyberduck-action:oauth",
"x-mountainduck-action:oauth"
],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": true,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": false,
"protocol": "openid-connect",
"attributes": {
"saml.assertion.signature": "false",
"saml.force.post.binding": "false",
"saml.multivalued.roles": "false",
"saml.encrypt": "false",
"oauth2.device.authorization.grant.enabled": "false",
"backchannel.logout.revoke.offline.tokens": "false",
"saml.server.signature": "false",
"saml.server.signature.keyinfo.ext": "false",
"exclude.session.state.from.auth.response": "false",
"oidc.ciba.grant.enabled": "false",
"backchannel.logout.session.required": "true",
"client_credentials.use_refresh_token": "false",
"saml_force_name_id_format": "false",
"saml.client.signature": "false",
"tls.client.certificate.bound.access.tokens": "false",
"saml.authnstatement": "false",
"display.on.consent.screen": "false",
"saml.onetimeuse.condition": "false"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [
"web-origins",
"profile",
"roles",
"groups",
"basic",
"email"
],
"optionalClientScopes": [
"address",
"phone",
"offline_access",
"microprofile-jwt"
],
"access": {
"view": true,
"configure": true,
"manage": true
}
}

View File

@@ -1,74 +0,0 @@
{
"clientId": "web",
"name": "OpenCloud Web App",
"description": "",
"rootUrl": "{{OC_URL}}",
"adminUrl": "{{OC_URL}}",
"baseUrl": "",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [
"{{OC_URL}}/",
"{{OC_URL}}/oidc-callback.html",
"{{OC_URL}}/oidc-silent-redirect.html"
],
"webOrigins": [
"{{OC_URL}}"
],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": true,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": false,
"protocol": "openid-connect",
"attributes": {
"saml.assertion.signature": "false",
"saml.force.post.binding": "false",
"saml.multivalued.roles": "false",
"saml.encrypt": "false",
"post.logout.redirect.uris": "+",
"oauth2.device.authorization.grant.enabled": "false",
"backchannel.logout.revoke.offline.tokens": "false",
"saml.server.signature": "false",
"saml.server.signature.keyinfo.ext": "false",
"exclude.session.state.from.auth.response": "false",
"oidc.ciba.grant.enabled": "false",
"backchannel.logout.url": "{{OC_URL}}/backchannel_logout",
"backchannel.logout.session.required": "true",
"client_credentials.use_refresh_token": "false",
"saml_force_name_id_format": "false",
"saml.client.signature": "false",
"tls.client.certificate.bound.access.tokens": "false",
"saml.authnstatement": "false",
"display.on.consent.screen": "false",
"saml.onetimeuse.condition": "false"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [
"web-origins",
"profile",
"roles",
"groups",
"basic",
"email"
],
"optionalClientScopes": [
"address",
"phone",
"offline_access",
"microprofile-jwt"
],
"access": {
"view": true,
"configure": true,
"manage": true
}
}

View File

@@ -1,8 +0,0 @@
#!/bin/bash
printenv
# replace openCloud domain in keycloak realm import
mkdir /opt/keycloak/data/import
sed -e "s/cloud.opencloud.test/${OC_DOMAIN}/g" /opt/keycloak/data/import-dist/opencloud-realm.json > /opt/keycloak/data/import/opencloud-realm.json
# run original docker-entrypoint
/opt/keycloak/bin/kc.sh "$@"

View File

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,6 @@ directives:
- 'https://${COMPANION_DOMAIN|companion.opencloud.test}/'
- 'wss://${COMPANION_DOMAIN|companion.opencloud.test}/'
- 'https://raw.githubusercontent.com/opencloud-eu/awesome-apps/'
- 'https://${KEYCLOAK_DOMAIN|keycloak.opencloud.test}/'
default-src:
- '''none'''
font-src:

View File

@@ -1,73 +0,0 @@
---
services:
traefik:
networks:
opencloud-net:
aliases:
- ${KEYCLOAK_DOMAIN:-keycloak.opencloud.test}
opencloud:
environment:
# Keycloak IDP specific configuration
PROXY_AUTOPROVISION_ACCOUNTS: "true"
PROXY_ROLE_ASSIGNMENT_DRIVER: "oidc"
OC_OIDC_ISSUER: https://${KEYCLOAK_DOMAIN:-keycloak.opencloud.test}/realms/${KEYCLOAK_REALM:-openCloud}
PROXY_OIDC_REWRITE_WELLKNOWN: "true"
WEB_OIDC_CLIENT_ID: ${OC_OIDC_CLIENT_ID:-web}
PROXY_USER_OIDC_CLAIM: "preferred_username"
PROXY_USER_CS3_CLAIM: "username"
OC_EXCLUDE_RUN_SERVICES: "idp"
OC_ADMIN_USER_ID: ""
GRAPH_ASSIGN_DEFAULT_USER_ROLE: "false"
GRAPH_USERNAME_MATCH: "none"
KEYCLOAK_DOMAIN: ${KEYCLOAK_DOMAIN:-keycloak.opencloud.test}
postgres:
image: postgres:alpine
networks:
opencloud-net:
volumes:
- keycloak_postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: keycloak
logging:
driver: ${LOG_DRIVER:-local}
restart: always
keycloak:
image: quay.io/keycloak/keycloak:25.0.0
networks:
opencloud-net:
command: ["start", "--proxy=edge", "--spi-connections-http-client-default-disable-trust-manager=${INSECURE:-false}", "--import-realm"]
entrypoint: ["/bin/sh", "/opt/keycloak/bin/docker-entrypoint-override.sh"]
volumes:
- "./config/keycloak/docker-entrypoint-override.sh:/opt/keycloak/bin/docker-entrypoint-override.sh"
- "./config/keycloak/opencloud-realm.dist.json:/opt/keycloak/data/import-dist/opencloud-realm.json"
environment:
OC_DOMAIN: ${OC_DOMAIN:-cloud.opencloud.test}
KC_HOSTNAME: ${KEYCLOAK_DOMAIN:-keycloak.opencloud.test}
KC_DB: postgres
KC_DB_URL: "jdbc:postgresql://postgres:5432/keycloak"
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: keycloak
KC_FEATURES: impersonation
KEYCLOAK_ADMIN: ${KEYCLOAK_ADMIN_USER:-admin}
KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD:-admin}
labels:
- "traefik.enable=true"
- "traefik.http.routers.keycloak.entrypoints=https"
- "traefik.http.routers.keycloak.rule=Host(`${KEYCLOAK_DOMAIN:-keycloak.opencloud.test}`)"
- "traefik.http.routers.keycloak.tls.certresolver=http"
- "traefik.http.routers.keycloak.service=keycloak"
- "traefik.http.services.keycloak.loadbalancer.server.port=8080"
depends_on:
- postgres
logging:
driver: ${LOG_DRIVER:-local}
restart: always
volumes:
keycloak_postgres_data:

View File

@@ -41,10 +41,7 @@ services:
NOTIFICATIONS_SMTP_PORT: "${SMTP_PORT}"
NOTIFICATIONS_SMTP_SENDER: "${SMTP_SENDER:-OpenCloud notifications <notifications@${OC_DOMAIN:-cloud.opencloud.test}>}"
NOTIFICATIONS_SMTP_USERNAME: "${SMTP_USERNAME}"
NOTIFICATIONS_SMTP_PASSWORD: "${SMTP_PASSWORD}"
NOTIFICATIONS_SMTP_INSECURE: "${SMTP_INSECURE}"
NOTIFICATIONS_SMTP_AUTHENTICATION: "${SMTP_AUTHENTICATION}"
NOTIFICATIONS_SMTP_ENCRYPTION: "${SMTP_TRANSPORT_ENCRYPTION}"
# make the registry available to the app provider containers
MICRO_REGISTRY_ADDRESS: 127.0.0.1:9233
NATS_NATS_HOST: 0.0.0.0

View File

@@ -6,10 +6,12 @@ services:
condition: service_completed_successfully
unzip-init:
image: opencloudeu/web-extensions:unzip-1.0.2
image: opencloudeu/web-extensions:unzip-1.0.0
user: root
volumes:
- opencloud-apps:/apps
entrypoint:
- /bin/sh
command: ["-c", "cp -R /usr/share/nginx/html/unzip/ /apps"]

View File

@@ -13,5 +13,5 @@ Please be patient, we are working on the content.
If you want to contribute to the dev docs, please visit [OpenCloud on Github](https://github.com/opencloud-eu/).
Contents will be transferred during the build process.
Contents will be transferred, during the build process.

28
go.mod
View File

@@ -33,7 +33,7 @@ require (
github.com/go-micro/plugins/v4/store/nats-js-kv v0.0.0-20240726082623-6831adfdcdc4
github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus v1.2.0
github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry v1.2.0
github.com/go-playground/validator/v10 v10.26.0
github.com/go-playground/validator/v10 v10.25.0
github.com/gofrs/uuid v4.4.0+incompatible
github.com/golang-jwt/jwt/v5 v5.2.2
github.com/golang/protobuf v1.5.4
@@ -55,15 +55,15 @@ require (
github.com/mitchellh/mapstructure v1.5.0
github.com/mna/pigeon v1.3.0
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
github.com/nats-io/nats-server/v2 v2.11.0
github.com/nats-io/nats-server/v2 v2.11.1
github.com/nats-io/nats.go v1.41.0
github.com/oklog/run v1.1.0
github.com/olekukonko/tablewriter v0.0.5
github.com/onsi/ginkgo v1.16.5
github.com/onsi/ginkgo/v2 v2.23.3
github.com/onsi/gomega v1.37.0
github.com/open-policy-agent/opa v1.3.0
github.com/opencloud-eu/reva/v2 v2.31.0
github.com/onsi/gomega v1.36.3
github.com/open-policy-agent/opa v1.2.0
github.com/opencloud-eu/reva/v2 v2.29.3
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
@@ -82,9 +82,9 @@ require (
github.com/test-go/testify v1.1.4
github.com/thejerf/suture/v4 v4.0.6
github.com/tidwall/gjson v1.18.0
github.com/tus/tusd/v2 v2.8.0
github.com/tus/tusd/v2 v2.7.1
github.com/unrolled/secure v1.16.0
github.com/urfave/cli/v2 v2.27.6
github.com/urfave/cli/v2 v2.27.5
github.com/xhit/go-simple-mail/v2 v2.16.0
go-micro.dev/v4 v4.11.0
go.etcd.io/bbolt v1.4.0
@@ -99,14 +99,14 @@ require (
golang.org/x/crypto v0.36.0
golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac
golang.org/x/image v0.25.0
golang.org/x/net v0.38.0
golang.org/x/net v0.37.0
golang.org/x/oauth2 v0.28.0
golang.org/x/sync v0.12.0
golang.org/x/term v0.30.0
golang.org/x/text v0.23.0
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb
google.golang.org/grpc v1.71.1
google.golang.org/protobuf v1.36.6
google.golang.org/grpc v1.71.0
google.golang.org/protobuf v1.36.5
gopkg.in/yaml.v2 v2.4.0
gotest.tools/v3 v3.5.2
stash.kopano.io/kgol/rndm v1.1.2
@@ -237,7 +237,7 @@ require (
github.com/juliangruber/go-intersect v1.1.0 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/libregraph/oidc-go v1.1.0 // indirect
github.com/longsleep/go-metrics v1.0.0 // indirect
@@ -246,7 +246,7 @@ require (
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mattn/go-sqlite3 v1.14.27 // indirect
github.com/mattn/go-sqlite3 v1.14.24 // indirect
github.com/maxymania/go-system v0.0.0-20170110133659-647cc364bf0b // indirect
github.com/mendsley/gojwk v0.0.0-20141217222730-4d5ec6e58103 // indirect
github.com/miekg/dns v1.1.57 // indirect
@@ -254,7 +254,7 @@ require (
github.com/minio/crc64nvme v1.0.1 // indirect
github.com/minio/highwayhash v1.0.3 // indirect
github.com/minio/md5-simd v1.1.2 // indirect
github.com/minio/minio-go/v7 v7.0.89 // indirect
github.com/minio/minio-go/v7 v7.0.88 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
@@ -325,7 +325,7 @@ require (
golang.org/x/time v0.11.0 // indirect
golang.org/x/tools v0.31.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect

66
go.sum
View File

@@ -258,8 +258,8 @@ github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS3
github.com/deepmap/oapi-codegen v1.3.11/go.mod h1:suMvK7+rKlx3+tpa8ByptmvoXbAV70wERKTOGH3hLp0=
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I=
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE=
github.com/dgraph-io/badger/v4 v4.6.0 h1:acOwfOOZ4p1dPRnYzvkVm7rUk2Y21TgPVepCy5dJdFQ=
github.com/dgraph-io/badger/v4 v4.6.0/go.mod h1:KSJ5VTuZNC3Sd+YhvVjk2nYua9UZnnTr/SkXvdtiPgI=
github.com/dgraph-io/badger/v4 v4.5.1 h1:7DCIXrQjo1LKmM96YD+hLVJ2EEsyyoWxJfpdd56HLps=
github.com/dgraph-io/badger/v4 v4.5.1/go.mod h1:qn3Be0j3TfV4kPbVoK0arXCD1/nr1ftth6sbL5jxdoA=
github.com/dgraph-io/ristretto v0.2.0 h1:XAfl+7cmoUDWW/2Lx8TGZQjjxIQ2Ley9DSf52dru4WE=
github.com/dgraph-io/ristretto v0.2.0/go.mod h1:8uBHCU/PBV4Ag0CJrP47b9Ofby5dqWNh4FicAdoqFNU=
github.com/dgraph-io/ristretto/v2 v2.1.0 h1:59LjpOJLNDULHh8MC4UaegN52lC4JnO2dITsie/Pa8I=
@@ -411,8 +411,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k=
github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
github.com/go-playground/validator/v10 v10.25.0 h1:5Dh7cjvzR7BRZadnsVOzPhWsrwUr0nmsZJxEAnFLNO8=
github.com/go-playground/validator/v10 v10.25.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8=
@@ -504,8 +504,8 @@ github.com/gomodule/redigo v1.9.2 h1:HrutZBLhSIU8abiSfW8pj8mPhOyMYjZT/wcA4/L9L9s
github.com/gomodule/redigo v1.9.2/go.mod h1:KsU3hiK/Ay8U42qpaJk+kuNa3C+spxapWpM+ywhcgtw=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q=
github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/flatbuffers v24.12.23+incompatible h1:ubBKR94NR4pXUCY/MUsRVzd9umNW7ht7EG9hHfS9FX8=
github.com/google/flatbuffers v24.12.23+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -689,8 +689,8 @@ github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHU
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
github.com/kobergj/gowebdav v0.0.0-20250102091030-aa65266db202 h1:A1xJ2NKgiYFiaHiLl9B5yw/gUBACSs9crDykTS3GuQI=
github.com/kobergj/gowebdav v0.0.0-20250102091030-aa65266db202/go.mod h1:bHA7t77X/QFExdeAnDzK6vKM34kEZAcE1OX4MfiwjkE=
github.com/kobergj/plugins/v4/store/nats-js-kv v0.0.0-20240807130109-f62bb67e8c90 h1:pfI8Z5yavO6fU6vDGlWhZ4BgDlvj8c6xB7J57HfTPwA=
@@ -768,8 +768,8 @@ github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.27 h1:drZCnuvf37yPfs95E5jd9s3XhdVWLal+6BOK6qrv6IU=
github.com/mattn/go-sqlite3 v1.14.27/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
@@ -789,8 +789,8 @@ github.com/minio/highwayhash v1.0.3 h1:kbnuUMoHYyVl7szWjSxJnxw11k2U709jqFPPmIUyD
github.com/minio/highwayhash v1.0.3/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
github.com/minio/minio-go/v7 v7.0.89 h1:hx4xV5wwTUfyv8LarhJAwNecnXpoTsj9v3f3q/ZkiJU=
github.com/minio/minio-go/v7 v7.0.89/go.mod h1:2rFnGAp02p7Dddo1Fq4S2wYOfpF0MUTSeLTRC90I204=
github.com/minio/minio-go/v7 v7.0.88 h1:v8MoIJjwYxOkehp+eiLIuvXk87P2raUtoU5klrAAshs=
github.com/minio/minio-go/v7 v7.0.88/go.mod h1:33+O8h0tO7pCeCWwBVa07RhVVfB/3vS4kEX7rwYKmIg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
@@ -827,8 +827,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04/go.mod h1:5sN+Lt1CaY4wsPvgQH/jsuJi4XO2ssZbdsIizr4CVC8=
github.com/nats-io/jwt/v2 v2.7.3 h1:6bNPK+FXgBeAqdj4cYQ0F8ViHRbi7woQLq4W29nUAzE=
github.com/nats-io/jwt/v2 v2.7.3/go.mod h1:GvkcbHhKquj3pkioy5put1wvPxs78UlZ7D/pY+BgZk4=
github.com/nats-io/nats-server/v2 v2.11.0 h1:fdwAT1d6DZW/4LUz5rkvQUe5leGEwjjOQYntzVRKvjE=
github.com/nats-io/nats-server/v2 v2.11.0/go.mod h1:leXySghbdtXSUmWem8K9McnJ6xbJOb0t9+NQ5HTRZjI=
github.com/nats-io/nats-server/v2 v2.11.1 h1:LwdauqMqMNhTxTN3+WFTX6wGDOKntHljgZ+7gL5HCnk=
github.com/nats-io/nats-server/v2 v2.11.1/go.mod h1:leXySghbdtXSUmWem8K9McnJ6xbJOb0t9+NQ5HTRZjI=
github.com/nats-io/nats.go v1.41.0 h1:PzxEva7fflkd+n87OtQTXqCTyLfIIMFJBpyccHLE2Ko=
github.com/nats-io/nats.go v1.41.0/go.mod h1:wV73x0FSI/orHPSYoyMeJB+KajMDoWyXmFaRrrYaaTo=
github.com/nats-io/nkeys v0.4.10 h1:glmRrpCmYLHByYcePvnTBEAwawwapjCPMjy2huw20wc=
@@ -861,12 +861,12 @@ github.com/onsi/ginkgo/v2 v2.23.3/go.mod h1:zXTP6xIp3U8aVuXN8ENK9IXRaTjFnpVB9mGm
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
github.com/open-policy-agent/opa v1.3.0 h1:zVvQvQg+9+FuSRBt4LgKNzJwsWl/c85kD5jPozJTydY=
github.com/open-policy-agent/opa v1.3.0/go.mod h1:t9iPNhaplD2qpiBqeudzJtEX3fKHK8zdA29oFvofAHo=
github.com/opencloud-eu/reva/v2 v2.31.0 h1:UVgeb0hSPoaDdqcKSJ7XZAhXCtHaVK9qm/JtFtJM/7U=
github.com/opencloud-eu/reva/v2 v2.31.0/go.mod h1:8MT1a/WJASZZhlSMC0oeE3ECQdjqFw3BUiiAIZ/JR8I=
github.com/onsi/gomega v1.36.3 h1:hID7cr8t3Wp26+cYnfcjR6HpJ00fdogN6dqZ1t6IylU=
github.com/onsi/gomega v1.36.3/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
github.com/open-policy-agent/opa v1.2.0 h1:88NDVCM0of1eO6Z4AFeL3utTEtMuwloFmWWU7dRV1z0=
github.com/open-policy-agent/opa v1.2.0/go.mod h1:30euUmOvuBoebRCcJ7DMF42bRBOPznvt0ACUMYDUGVY=
github.com/opencloud-eu/reva/v2 v2.29.3 h1:y0vfye984kOIB9nib4LkN3wEnJ2vR0/1CKoVcIRQ7JI=
github.com/opencloud-eu/reva/v2 v2.29.3/go.mod h1:+nkCU7w6E6cyNSsKRYj1rb0cCI7QswEQ7KOPljctebM=
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=
@@ -1098,13 +1098,13 @@ github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208/go.mod h1:BzWtXXrXz
github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g=
github.com/trustelem/zxcvbn v1.0.1 h1:mp4JFtzdDYGj9WYSD3KQSkwwUumWNFzXaAjckaTYpsc=
github.com/trustelem/zxcvbn v1.0.1/go.mod h1:zonUyKeh7sw6psPf/e3DtRqkRyZvAbOfjNz/aO7YQ5s=
github.com/tus/tusd/v2 v2.8.0 h1:X2jGxQ05jAW4inDd2ogmOKqwnb4c/D0lw2yhgHayWyU=
github.com/tus/tusd/v2 v2.8.0/go.mod h1:3/zEOVQQIwmJhvNam8phV4x/UQt68ZmZiTzeuJUNhVo=
github.com/tus/tusd/v2 v2.7.1 h1:TGJjhv9RYXDmsTz8ug/qSd9vQpmD0Ik0G0IPo80Qmc0=
github.com/tus/tusd/v2 v2.7.1/go.mod h1:PLdIMQ/ge+5ADgGKcL3FgTaPs+7wB0JIiI5HQXAiJE8=
github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/urfave/cli/v2 v2.27.6 h1:VdRdS98FNhKZ8/Az8B7MTyGQmpIr36O1EHybx/LaZ4g=
github.com/urfave/cli/v2 v2.27.6/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
@@ -1177,8 +1177,6 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0f
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 h1:m639+BofXTvcY1q8CGs4ItwQarYtJPOWmVobfM1HpVI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0/go.mod h1:LjReUci/F4BUyv+y4dwnq3h/26iNOeC3wAIqgvTIZVo=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk=
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
@@ -1330,8 +1328,8 @@ golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1599,8 +1597,8 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb h1:ITgPrl429bc6+2ZraNSzMDk3I95nmQln2fuPstKwFDE=
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:sAo5UzpjUwgFBCzupwhcLcxHVDK7vG5IqI30YnwX2eE=
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 h1:ToEetK57OidYuqD4Q5w+vfEnPvPpuTwedCNVohYJfNk=
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697/go.mod h1:JJrvXBWRZaFMxBufik1a4RpFw4HhgVtBBWQeQgUj2cc=
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950=
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4=
@@ -1620,8 +1618,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI=
google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
google.golang.org/grpc/examples v0.0.0-20211102180624-670c133e568e h1:m7aQHHqd0q89mRwhwS9Bx2rjyl/hsFAeta+uGrHsQaU=
google.golang.org/grpc/examples v0.0.0-20211102180624-670c133e568e/go.mod h1:gID3PKrg7pWKntu9Ss6zTLJ0ttC0X9IHgREOCZwbCVU=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
@@ -1638,8 +1636,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y=
gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UDAkHu8BrjI=

View File

@@ -2716,7 +2716,7 @@ var (
// errMaxExprCnt is used to signal that the maximum number of
// expressions have been parsed.
errMaxExprCnt = errors.New("max number of expressions parsed")
errMaxExprCnt = errors.New("max number of expresssions parsed")
)
// Option is a function that can set an option on the parser. It returns

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.53.2. DO NOT EDIT.
// Code generated by mockery v2.53.0. DO NOT EDIT.
package mocks

View File

@@ -16,7 +16,7 @@ var (
// LatestTag is the latest released version plus the dev meta version.
// Will be overwritten by the release pipeline
// Needs a manual change for every tagged release
LatestTag = "2.0.0+dev"
LatestTag = "2.0.1+dev"
// Date indicates the build date.
// This has been removed, it looks like you can only replace static strings with recent go versions
@@ -46,17 +46,18 @@ func GetString() string {
// Parsed returns a semver Version
func Parsed() (version *semver.Version) {
versionToParse := LatestTag
// use the placeholder version if the tag is empty or when we are creating a daily build
if Tag != "" && Tag != "daily" {
if Tag != "" {
versionToParse = Tag
}
version, err := semver.NewVersion(versionToParse)
// We have no semver version but a commitid
if err != nil {
// this should never happen
return &semver.Version{}
if err != nil {
return &semver.Version{}
}
}
if String != "" {
// We have no tagged version but a commitid
nVersion, err := version.SetMetadata(String)
if err != nil {
return &semver.Version{}

View File

@@ -1,49 +1,124 @@
export default {
changeTypes: [
{
title: '💥 Breaking changes',
labels: ['breaking', 'Type:Breaking-Change'],
bump: 'major',
weight: 3
},
{
title: '🔒 Security',
labels: ['security', 'Type:Security'],
bump: 'patch',
weight: 2
},
{
title: '✨ Features',
labels: ['feature', 'Type:Feature'],
bump: 'minor',
weight: 1
},
{
title: '📈 Enhancement',
labels: ['enhancement', 'refactor', 'Type:Enhancement'],
bump: 'minor'
},
{
title: '🐛 Bug Fixes',
labels: ['bug', 'Type:Bug'],
bump: 'patch'
},
{
title: '📚 Documentation',
labels: ['docs', 'documentation', 'Type:Documentation'],
bump: 'patch'
},
{
title: '✅ Tests',
labels: ['test', 'tests', 'Type:Test'],
bump: 'patch'
},
{
title: '📦️ Dependencies',
labels: ['dependency', 'dependencies', 'Type:Dependencies'],
bump: 'patch',
weight: -1
}
],
useVersionPrefixV: true,
}
changeTypes: [
{
title: "💥 Breaking changes",
labels: ["breaking", "Type:Breaking-Change"],
bump: "major",
weight: 3,
},
{
title: "🔒 Security",
labels: ["security", "Type:Security"],
bump: "patch",
weight: 2,
},
{
title: "✨ Features",
labels: ["feature", "Type:Feature"],
bump: "minor",
weight: 1,
},
{
title: "📈 Enhancement",
labels: ["enhancement", "refactor", "Type:Enhancement"],
bump: "minor",
},
{
title: "🐛 Bug Fixes",
labels: ["bug", "Type:Bug"],
bump: "patch",
},
{
title: "📚 Documentation",
labels: ["docs", "documentation", "Type:Documentation"],
bump: "patch",
},
{
title: "✅ Tests",
labels: ["test", "tests", "Type:Test"],
bump: "patch",
},
{
title: "📦️ Dependencies",
labels: ["dependency", "dependencies", "Type:Dependencies"],
bump: "patch",
weight: -1,
},
],
useVersionPrefixV: true,
getLatestTag: ({ exec }) => {
// the plugin uses the latest tag to determine the next version
// and the changes that are included in the upcoming release.
const branch = getBranch(exec);
let tags = getTags(exec);
if (branch.startsWith("stable-")) {
const [_, majorAndMinor] = branch.split("-");
// we only care about tags that are within the range of the current stable branch.
// e.g. if the branch is stable-1.2, we only care about tags that are v1.2.x.
const matchingTags = tags.filter((t) =>
t.startsWith(`v${majorAndMinor}`)
);
if (matchingTags.length) {
tags = matchingTags;
}
}
return tags.pop() || "v0.0.0";
},
useLatestRelease: ({ exec, nextVersion }) => {
// check if the release should be marked as latest release on GitHub.
const tags = getTags(exec);
const latestTag = tags.pop() || "v0.0.0";
return compareVersions(latestTag, nextVersion) === -1;
},
};
const parseVersion = (tag: string) => {
const version = tag.startsWith("v") ? tag.slice(1) : tag;
const [main, pre] = version.split("-");
const [major, minor, patch] = main.split(".").map(Number);
return { major, minor, patch, pre };
};
const getBranch = (exec: any): string => {
return exec("git rev-parse --abbrev-ref HEAD", {
silent: true,
}).stdout.trim();
};
const getTags = (exec: any) => {
exec("git fetch --tags", { silent: true });
const tagsOutput = exec("git tag", { silent: true }).stdout.trim();
const tags: string[] = tagsOutput ? tagsOutput.split("\n") : [];
return tags.filter((tag) => tag.startsWith("v")).sort(compareVersions);
};
const compareVersions = (a: string, b: string) => {
const va = parseVersion(a);
const vb = parseVersion(b);
if (va.major !== vb.major) {
return va.major - vb.major;
}
if (va.minor !== vb.minor) {
return va.minor - vb.minor;
}
if (va.patch !== vb.patch) {
return va.patch - vb.patch;
}
if (va.pre && !vb.pre) {
return -1;
}
if (!va.pre && vb.pre) {
return 1;
}
if (va.pre && vb.pre) {
return va.pre.localeCompare(vb.pre);
}
return 0;
};

View File

@@ -33,17 +33,11 @@ See the environment variables for more details.
### Maximum Scan Size
Several factors can make it necessary to limit the maximum filesize the antivirus service uses for scanning.
Use the `ANTIVIRUS_MAX_SCAN_SIZE` environment variable to scan only a given number of bytes,
or to skip the whole resource.
Use the `ANTIVIRUS_MAX_SCAN_SIZE` environment variable to specify the maximum file size to be scanned.
Even if it's recommended to scan the whole file, several factors like scanner type and version,
Even if it's recommended to scan each file, several factors like scanner type and version,
bandwidth, performance issues, etc. might make a limit necessary.
In such cases, the antivirus the max scan size mode can be handy, the following modes are available:
- `partial`: The file is scanned up to the given size. The rest of the file is not scanned. This is the default mode `ANTIVIRUS_MAX_SCAN_SIZE=partial`
- `skip`: The file is skipped and not scanned. `ANTIVIRUS_MAX_SCAN_SIZE=skip`
**IMPORTANT**
> Streaming of files to the virus scan service still [needs to be implemented](https://github.com/owncloud/ocis/issues/6803).
> To prevent OOM errors `ANTIVIRUS_MAX_SCAN_SIZE` needs to be set lower than available ram and or the maximum file size that can be scanned by the virus scanner.

View File

@@ -45,7 +45,7 @@ func Server(cfg *config.Config) *cli.Command {
{
svc, err := service.NewAntivirus(cfg, logger, traceProvider)
if err != nil {
return cli.Exit(err.Error(), 1)
return err
}
gr.Add(svc.Run, func(_ error) {

View File

@@ -5,26 +5,6 @@ import (
"time"
)
// ScannerType gives info which scanner is used
type ScannerType string
const (
// ScannerTypeClamAV defines that clamav is used
ScannerTypeClamAV ScannerType = "clamav"
// ScannerTypeICap defines that icap is used
ScannerTypeICap ScannerType = "icap"
)
// MaxScanSizeMode defines the mode of handling files that exceed the maximum scan size
type MaxScanSizeMode string
const (
// MaxScanSizeModeSkip defines that files that are bigger than the max scan size will be skipped
MaxScanSizeModeSkip MaxScanSizeMode = "skip"
// MaxScanSizeModePartial defines that only the file up to the max size will be used
MaxScanSizeModePartial MaxScanSizeMode = "partial"
)
// Config combines all available configuration parts.
type Config struct {
File string
@@ -40,9 +20,8 @@ type Config struct {
Events Events
Workers int `yaml:"workers" env:"ANTIVIRUS_WORKERS" desc:"The number of concurrent go routines that fetch events from the event queue." introductionVersion:"1.0.0"`
Scanner Scanner
MaxScanSize string `yaml:"max-scan-size" env:"ANTIVIRUS_MAX_SCAN_SIZE" desc:"The maximum scan size the virus scanner can handle.0 means unlimited. Usable common abbreviations: [KB, KiB, MB, MiB, GB, GiB, TB, TiB, PB, PiB, EB, EiB], example: 2GB." introductionVersion:"1.0.0"`
MaxScanSizeMode MaxScanSizeMode `yaml:"max-scan-size-mode" env:"ANTIVIRUS_MAX_SCAN_SIZE_MODE" desc:"Defines the mode of handling files that exceed the maximum scan size. Supported options are: 'skip', which skips files that are bigger than the max scan size, and 'truncate' (default), which only uses the file up to the max size." introductionVersion:"2.1.0"`
Scanner Scanner
MaxScanSize string `yaml:"max-scan-size" env:"ANTIVIRUS_MAX_SCAN_SIZE" desc:"The maximum scan size the virus scanner can handle. 0 means unlimited. Usable common abbreviations: [KB, KiB, MB, MiB, GB, GiB, TB, TiB, PB, PiB, EB, EiB], example: 2GB." introductionVersion:"1.0.0"`
Context context.Context `json:"-" yaml:"-"`
@@ -83,7 +62,7 @@ type Events struct {
// Scanner provides configuration options for the virus scanner
type Scanner struct {
Type ScannerType `yaml:"type" env:"ANTIVIRUS_SCANNER_TYPE" desc:"The antivirus scanner to use. Supported values are 'clamav' and 'icap'." introductionVersion:"1.0.0"`
Type string `yaml:"type" env:"ANTIVIRUS_SCANNER_TYPE" desc:"The antivirus scanner to use. Supported values are 'clamav' and 'icap'." introductionVersion:"1.0.0"`
ClamAV ClamAV // only if Type == clamav
ICAP ICAP // only if Type == icap
@@ -91,8 +70,7 @@ type Scanner struct {
// ClamAV provides configuration option for clamav
type ClamAV struct {
Socket string `yaml:"socket" env:"ANTIVIRUS_CLAMAV_SOCKET" desc:"The socket clamav is running on. Note the default value is an example which needs adaption according your OS." introductionVersion:"1.0.0"`
Timeout time.Duration `yaml:"scan_timeout" env:"ANTIVIRUS_CLAMAV_SCAN_TIMEOUT" desc:"Scan timeout for the ClamAV client. Defaults to '5m' (5 minutes). See the Environment Variable Types description for more details." introductionVersion:"2.1.0"`
Socket string `yaml:"socket" env:"ANTIVIRUS_CLAMAV_SOCKET" desc:"The socket clamav is running on. Note the default value is an example which needs adaption according your OS." introductionVersion:"1.0.0"`
}
// ICAP provides configuration options for icap

View File

@@ -30,15 +30,10 @@ func DefaultConfig() *config.Config {
},
Workers: 10,
InfectedFileHandling: "delete",
// defaults from clamav sample conf: MaxScanSize=400M, MaxFileSize=100M, StreamMaxLength=100M
// https://github.com/Cisco-Talos/clamav/blob/main/etc/clamd.conf.sample
MaxScanSize: "100MB",
MaxScanSizeMode: config.MaxScanSizeModePartial,
Scanner: config.Scanner{
Type: config.ScannerTypeClamAV,
Type: "clamav",
ClamAV: config.ClamAV{
Socket: "/run/clamav/clamd.ctl",
Timeout: 5 * time.Minute,
Socket: "/run/clamav/clamd.ctl",
},
ICAP: config.ICAP{
URL: "icap://127.0.0.1:1344",
@@ -62,9 +57,4 @@ func EnsureDefaults(cfg *config.Config) {
// Sanitize sanitizes the configuration
func Sanitize(cfg *config.Config) {
defaultConfig := DefaultConfig()
if cfg.MaxScanSize == "" {
cfg.MaxScanSize = defaultConfig.MaxScanSize
}
}

View File

@@ -1,51 +1,34 @@
package scanners
import (
"fmt"
"time"
"github.com/dutchcoders/go-clamd"
)
// NewClamAV returns a Scanner talking to clamAV via socket
func NewClamAV(socket string, timeout time.Duration) (*ClamAV, error) {
c := clamd.NewClamd(socket)
if err := c.Ping(); err != nil {
return nil, fmt.Errorf("%w: %w", ErrScannerNotReachable, err)
}
func NewClamAV(socket string) *ClamAV {
return &ClamAV{
clamd: clamd.NewClamd(socket),
timeout: timeout,
}, nil
clamd: clamd.NewClamd(socket),
}
}
// ClamAV is a Scanner based on clamav
type ClamAV struct {
clamd *clamd.Clamd
timeout time.Duration
clamd *clamd.Clamd
}
// Scan to fulfill Scanner interface
func (s ClamAV) Scan(in Input) (Result, error) {
abort := make(chan bool, 1)
defer close(abort)
ch, err := s.clamd.ScanStream(in.Body, abort)
ch, err := s.clamd.ScanStream(in.Body, make(chan bool))
if err != nil {
return Result{}, err
}
select {
case <-time.After(s.timeout):
abort <- true
return Result{}, fmt.Errorf("%w: %s", ErrScanTimeout, in.Url)
case s := <-ch:
return Result{
Infected: s.Status == clamd.RES_FOUND,
Description: s.Description,
ScanTime: time.Now(),
}, nil
}
r := <-ch
return Result{
Infected: r.Status == clamd.RES_FOUND,
Description: r.Description,
ScanTime: time.Now(),
}, nil
}

View File

@@ -1,120 +0,0 @@
package scanners_test
import (
"context"
"net"
"os"
"path/filepath"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/opencloud-eu/opencloud/services/antivirus/pkg/scanners"
)
func newUnixListener(t testing.TB, lc net.ListenConfig, v ...string) net.Listener {
d, err := os.MkdirTemp("", "")
assert.NoError(t, err)
t.Cleanup(func() {
require.NoError(t, os.RemoveAll(d))
})
nl, err := lc.Listen(context.Background(), "unix", filepath.Join(d, "sock"))
require.NoError(t, err)
go func() {
i := 0
for {
if len(v) == i {
break
}
conn, err := nl.Accept()
require.NoError(t, err)
time.Sleep(100 * time.Millisecond)
_, err = conn.Write([]byte(v[i]))
require.NoError(t, err)
require.NoError(t, conn.Close())
i++
}
}()
return nl
}
func TestNewClamAV(t *testing.T) {
t.Run("returns a scanner", func(t *testing.T) {
ul := newUnixListener(t, net.ListenConfig{}, "PONG\n")
defer func() {
assert.NoError(t, ul.Close())
}()
done := make(chan bool, 1)
go func() {
_, err := scanners.NewClamAV(ul.Addr().String(), 10*time.Second)
assert.NoError(t, err)
done <- true
}()
assert.True(t, <-done)
})
t.Run("fails if scanner is not pingable", func(t *testing.T) {
_, err := scanners.NewClamAV("", 0)
assert.ErrorIs(t, err, scanners.ErrScannerNotReachable)
})
}
func TestNewClamAV_Scan(t *testing.T) {
t.Run("returns a result", func(t *testing.T) {
ul := newUnixListener(t, net.ListenConfig{}, "PONG\n", "stream: Win.Test.EICAR_HDB-1 FOUND\n")
defer func() {
assert.NoError(t, ul.Close())
}()
done := make(chan bool, 1)
go func() {
scanner, err := scanners.NewClamAV(ul.Addr().String(), 10*time.Second)
assert.NoError(t, err)
result, err := scanner.Scan(scanners.Input{Body: strings.NewReader("DATA")})
assert.NoError(t, err)
assert.Equal(t, result.Description, "Win.Test.EICAR_HDB-1")
assert.True(t, result.Infected)
done <- true
}()
assert.True(t, <-done)
})
t.Run("aborts after a certain time", func(t *testing.T) {
ul := newUnixListener(t, net.ListenConfig{}, "PONG\n", "stream: Win.Test.EICAR_HDB-1 FOUND\n")
defer func() {
assert.NoError(t, ul.Close())
}()
done := make(chan bool, 1)
go func() {
scanner, err := scanners.NewClamAV(ul.Addr().String(), 10*time.Second)
assert.NoError(t, err)
result, err := scanner.Scan(scanners.Input{Body: strings.NewReader("DATA")})
assert.NoError(t, err)
assert.Equal(t, result.Description, "Win.Test.EICAR_HDB-1")
assert.True(t, result.Infected)
done <- true
}()
assert.True(t, <-done)
})
}

View File

@@ -1,31 +1,21 @@
package scanners
import (
"errors"
"io"
"time"
)
var (
// ErrScanTimeout is returned when a scan times out
ErrScanTimeout = errors.New("time out waiting for clamav to respond while scanning")
// ErrScannerNotReachable is returned when the scanner is not reachable
ErrScannerNotReachable = errors.New("failed to reach the scanner")
)
// The Result is the common scan result to all scanners
type Result struct {
Infected bool
ScanTime time.Time
Description string
}
type (
// The Result is the common scan result to all scanners
Result struct {
Infected bool
ScanTime time.Time
Description string
}
// The Input is the common input to all scanners
Input struct {
Body io.Reader
Size int64
Url string
Name string
}
)
// The Input is the common input to all scanners
type Input struct {
Body io.Reader
Size int64
Url string
Name string
}

View File

@@ -9,7 +9,6 @@ import (
"io"
"net/http"
"os"
"slices"
"sync"
"time"
@@ -38,44 +37,38 @@ type Scanner interface {
}
// NewAntivirus returns a service implementation for Service.
func NewAntivirus(cfg *config.Config, logger log.Logger, tracerProvider trace.TracerProvider) (Antivirus, error) {
func NewAntivirus(c *config.Config, l log.Logger, tp trace.TracerProvider) (Antivirus, error) {
var scanner Scanner
var err error
switch cfg.Scanner.Type {
switch c.Scanner.Type {
default:
return Antivirus{}, fmt.Errorf("unknown av scanner: '%s'", cfg.Scanner.Type)
case config.ScannerTypeClamAV:
scanner, err = scanners.NewClamAV(cfg.Scanner.ClamAV.Socket, cfg.Scanner.ClamAV.Timeout)
case config.ScannerTypeICap:
scanner, err = scanners.NewICAP(cfg.Scanner.ICAP.URL, cfg.Scanner.ICAP.Service, cfg.Scanner.ICAP.Timeout)
return Antivirus{}, fmt.Errorf("unknown av scanner: '%s'", c.Scanner.Type)
case "clamav":
scanner = scanners.NewClamAV(c.Scanner.ClamAV.Socket)
case "icap":
scanner, err = scanners.NewICAP(c.Scanner.ICAP.URL, c.Scanner.ICAP.Service, c.Scanner.ICAP.Timeout)
}
if err != nil {
return Antivirus{}, err
}
av := Antivirus{config: cfg, log: logger, tracerProvider: tracerProvider, scanner: scanner, client: rhttp.GetHTTPClient(rhttp.Insecure(true))}
av := Antivirus{c: c, l: l, tp: tp, s: scanner, client: rhttp.GetHTTPClient(rhttp.Insecure(true))}
switch mode := cfg.MaxScanSizeMode; mode {
case config.MaxScanSizeModeSkip, config.MaxScanSizeModePartial:
break
default:
return av, fmt.Errorf("unknown max scan size mode '%s'", cfg.MaxScanSizeMode)
}
switch outcome := events.PostprocessingOutcome(cfg.InfectedFileHandling); outcome {
switch o := events.PostprocessingOutcome(c.InfectedFileHandling); o {
case events.PPOutcomeContinue, events.PPOutcomeAbort, events.PPOutcomeDelete:
av.outcome = outcome
av.o = o
default:
return av, fmt.Errorf("unknown infected file handling '%s'", outcome)
return av, fmt.Errorf("unknown infected file handling '%s'", o)
}
if cfg.MaxScanSize != "" {
b, err := bytesize.Parse(cfg.MaxScanSize)
if c.MaxScanSize != "" {
b, err := bytesize.Parse(c.MaxScanSize)
if err != nil {
return av, err
}
av.maxScanSize = b.Bytes()
av.m = b.Bytes()
}
return av, nil
@@ -83,23 +76,23 @@ func NewAntivirus(cfg *config.Config, logger log.Logger, tracerProvider trace.Tr
// Antivirus defines implements the business logic for Service.
type Antivirus struct {
config *config.Config
log log.Logger
scanner Scanner
outcome events.PostprocessingOutcome
maxScanSize uint64
tracerProvider trace.TracerProvider
c *config.Config
l log.Logger
s Scanner
o events.PostprocessingOutcome
m uint64
tp trace.TracerProvider
client *http.Client
}
// Run runs the service
func (av Antivirus) Run() error {
eventsCfg := av.config.Events
evtsCfg := av.c.Events
var rootCAPool *x509.CertPool
if av.config.Events.TLSRootCACertificate != "" {
rootCrtFile, err := os.Open(eventsCfg.TLSRootCACertificate)
if av.c.Events.TLSRootCACertificate != "" {
rootCrtFile, err := os.Open(evtsCfg.TLSRootCACertificate)
if err != nil {
return err
}
@@ -111,10 +104,10 @@ func (av Antivirus) Run() error {
rootCAPool = x509.NewCertPool()
rootCAPool.AppendCertsFromPEM(certBytes.Bytes())
av.config.Events.TLSInsecure = false
av.c.Events.TLSInsecure = false
}
natsStream, err := stream.NatsFromConfig(av.config.Service.Name, false, stream.NatsConfig(av.config.Events))
natsStream, err := stream.NatsFromConfig(av.c.Service.Name, false, stream.NatsConfig(av.c.Events))
if err != nil {
return err
}
@@ -125,7 +118,7 @@ func (av Antivirus) Run() error {
}
wg := sync.WaitGroup{}
for i := 0; i < av.config.Workers; i++ {
for i := 0; i < av.c.Workers; i++ {
wg.Add(1)
go func() {
defer wg.Done()
@@ -134,11 +127,11 @@ func (av Antivirus) Run() error {
if err != nil {
switch {
case errors.Is(err, ErrFatal):
av.log.Fatal().Err(err).Msg("fatal error - exiting")
av.l.Fatal().Err(err).Msg("fatal error - exiting")
case errors.Is(err, ErrEvent):
av.log.Error().Err(err).Msg("continuing")
av.l.Error().Err(err).Msg("continuing")
default:
av.log.Fatal().Err(err).Msg("unknown error - exiting")
av.l.Fatal().Err(err).Msg("unknown error - exiting")
}
}
}
@@ -150,20 +143,20 @@ func (av Antivirus) Run() error {
}
func (av Antivirus) processEvent(e events.Event, s events.Publisher) error {
ctx, span := av.tracerProvider.Tracer("antivirus").Start(e.GetTraceContext(context.Background()), "processEvent")
ctx := e.GetTraceContext(context.Background())
ctx, span := av.tp.Tracer("antivirus").Start(ctx, "processEvent")
defer span.End()
av.log.Info().Str("traceID", span.SpanContext().TraceID().String()).Msg("TraceID")
av.l.Info().Str("traceID", span.SpanContext().TraceID().String()).Msg("TraceID")
ev := e.Event.(events.StartPostprocessingStep)
if ev.StepToStart != events.PPStepAntivirus {
return nil
}
if av.config.DebugScanOutcome != "" {
av.log.Warn().Str("antivir, clamav", ">>>>>>> ANTIVIRUS_DEBUG_SCAN_OUTCOME IS SET NO ACTUAL VIRUS SCAN IS PERFORMED!").Send()
if av.c.DebugScanOutcome != "" {
av.l.Warn().Str("antivir, clamav", ">>>>>>> ANTIVIRUS_DEBUG_SCAN_OUTCOME IS SET NO ACTUAL VIRUS SCAN IS PERFORMED!").Send()
if err := events.Publish(ctx, s, events.PostprocessingStepFinished{
FinishedStep: events.PPStepAntivirus,
Outcome: events.PostprocessingOutcome(av.config.DebugScanOutcome),
Outcome: events.PostprocessingOutcome(av.c.DebugScanOutcome),
UploadID: ev.UploadID,
ExecutingUser: ev.ExecutingUser,
Filename: ev.Filename,
@@ -174,14 +167,13 @@ func (av Antivirus) processEvent(e events.Event, s events.Publisher) error {
ResourceID: ev.ResourceID,
},
}); err != nil {
av.log.Fatal().Err(err).Str("uploadid", ev.UploadID).Interface("resourceID", ev.ResourceID).Msg("cannot publish events - exiting")
av.l.Fatal().Err(err).Str("uploadid", ev.UploadID).Interface("resourceID", ev.ResourceID).Msg("cannot publish events - exiting")
return fmt.Errorf("%w: cannot publish events", ErrFatal)
}
return fmt.Errorf("%w: no actual virus scan performed", ErrEvent)
}
av.log.Debug().Str("uploadid", ev.UploadID).Str("filename", ev.Filename).Msg("Starting virus scan.")
av.l.Debug().Str("uploadid", ev.UploadID).Str("filename", ev.Filename).Msg("Starting virus scan.")
var errmsg string
start := time.Now()
res, err := av.process(ev)
@@ -193,17 +185,17 @@ func (av Antivirus) processEvent(e events.Event, s events.Publisher) error {
var outcome events.PostprocessingOutcome
switch {
case res.Infected:
outcome = av.outcome
outcome = av.o
case !res.Infected && err == nil:
outcome = events.PPOutcomeContinue
case err != nil:
outcome = events.PPOutcomeRetry
default:
// Not sure what this is about. Abort.
// Not sure what this is about. abort.
outcome = events.PPOutcomeAbort
}
av.log.Info().Str("uploadid", ev.UploadID).Interface("resourceID", ev.ResourceID).Str("virus", res.Description).Str("outcome", string(outcome)).Str("filename", ev.Filename).Str("user", ev.ExecutingUser.GetId().GetOpaqueId()).Bool("infected", res.Infected).Dur("duration", duration).Msg("File scanned")
av.l.Info().Str("uploadid", ev.UploadID).Interface("resourceID", ev.ResourceID).Str("virus", res.Description).Str("outcome", string(outcome)).Str("filename", ev.Filename).Str("user", ev.ExecutingUser.GetId().GetOpaqueId()).Bool("infected", res.Infected).Dur("duration", duration).Msg("File scanned")
if err := events.Publish(ctx, s, events.PostprocessingStepFinished{
FinishedStep: events.PPStepAntivirus,
Outcome: outcome,
@@ -218,7 +210,7 @@ func (av Antivirus) processEvent(e events.Event, s events.Publisher) error {
ErrorMsg: errmsg,
},
}); err != nil {
av.log.Fatal().Err(err).Str("uploadid", ev.UploadID).Interface("resourceID", ev.ResourceID).Msg("cannot publish events - exiting")
av.l.Fatal().Err(err).Str("uploadid", ev.UploadID).Interface("resourceID", ev.ResourceID).Msg("cannot publish events - exiting")
return fmt.Errorf("%w: %s", ErrFatal, err)
}
return nil
@@ -226,24 +218,11 @@ func (av Antivirus) processEvent(e events.Event, s events.Publisher) error {
// process the scan
func (av Antivirus) process(ev events.StartPostprocessingStep) (scanners.Result, error) {
if ev.Filesize == 0 {
av.log.Info().Str("uploadid", ev.UploadID).Msg("Skipping file to be virus scanned, file size is 0.")
return scanners.Result{ScanTime: time.Now()}, nil
}
headers := make(map[string]string)
switch {
case av.maxScanSize == 0:
// there is no size limit
break
case av.config.MaxScanSizeMode == config.MaxScanSizeModeSkip && ev.Filesize > av.maxScanSize:
// skip the file if it is bigger than the max scan size
av.log.Info().Str("uploadid", ev.UploadID).Uint64("filesize", ev.Filesize).
Msg("Skipping file to be virus scanned, file size is bigger than max scan size.")
return scanners.Result{ScanTime: time.Now()}, nil
case av.config.MaxScanSizeMode == config.MaxScanSizeModePartial && ev.Filesize > av.maxScanSize:
// set the range header to only download the first maxScanSize bytes
headers["Range"] = fmt.Sprintf("bytes=0-%d", av.maxScanSize-1)
if ev.Filesize == 0 || (0 < av.m && av.m < ev.Filesize) {
av.l.Info().Str("uploadid", ev.UploadID).Uint64("limit", av.m).Uint64("filesize", ev.Filesize).Msg("Skipping file to be virus scanned because its file size is higher than the defined limit.")
return scanners.Result{
ScanTime: time.Now(),
}, nil
}
var err error
@@ -251,61 +230,56 @@ func (av Antivirus) process(ev events.StartPostprocessingStep) (scanners.Result,
switch ev.UploadID {
default:
rrc, err = av.downloadViaToken(ev.URL, headers)
rrc, err = av.downloadViaToken(ev.URL)
case "":
rrc, err = av.downloadViaReva(ev.URL, ev.Token, ev.RevaToken, headers)
rrc, err = av.downloadViaReva(ev.URL, ev.Token, ev.RevaToken)
}
if err != nil {
av.log.Error().Err(err).Str("uploadid", ev.UploadID).Msg("error downloading file")
av.l.Error().Err(err).Str("uploadid", ev.UploadID).Msg("error downloading file")
return scanners.Result{}, err
}
defer func() {
_ = rrc.Close()
}()
defer rrc.Close()
av.l.Debug().Str("uploadid", ev.UploadID).Msg("Downloaded file successfully, starting virusscan")
av.log.Debug().Str("uploadid", ev.UploadID).Msg("Downloaded file successfully, starting virusscan")
res, err := av.scanner.Scan(scanners.Input{Body: rrc, Size: int64(ev.Filesize), Url: ev.URL, Name: ev.Filename})
res, err := av.s.Scan(scanners.Input{Body: rrc, Size: int64(ev.Filesize), Url: ev.URL, Name: ev.Filename})
if err != nil {
av.log.Error().Err(err).Str("uploadid", ev.UploadID).Msg("error scanning file")
av.l.Error().Err(err).Str("uploadid", ev.UploadID).Msg("error scanning file")
}
return res, err
}
// download will download the file
func (av Antivirus) downloadViaToken(url string, headers map[string]string) (io.ReadCloser, error) {
func (av Antivirus) downloadViaToken(url string) (io.ReadCloser, error) {
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, err
}
return av.doDownload(req, headers)
return av.doDownload(req)
}
// download will download the file
func (av Antivirus) downloadViaReva(url string, dltoken string, revatoken string, headers map[string]string) (io.ReadCloser, error) {
req, err := rhttp.NewRequest(ctxpkg.ContextSetToken(context.Background(), revatoken), http.MethodGet, url, nil)
func (av Antivirus) downloadViaReva(url string, dltoken string, revatoken string) (io.ReadCloser, error) {
ctx := ctxpkg.ContextSetToken(context.Background(), revatoken)
req, err := rhttp.NewRequest(ctx, http.MethodGet, url, nil)
if err != nil {
return nil, err
}
req.Header.Set("X-Reva-Transfer", dltoken)
return av.doDownload(req, headers)
return av.doDownload(req)
}
func (av Antivirus) doDownload(req *http.Request, headers map[string]string) (io.ReadCloser, error) {
for k, v := range headers {
req.Header.Add(k, v)
}
func (av Antivirus) doDownload(req *http.Request) (io.ReadCloser, error) {
res, err := av.client.Do(req)
if err != nil {
return nil, err
}
if !slices.Contains([]int{http.StatusOK, http.StatusPartialContent}, res.StatusCode) {
_ = res.Body.Close()
if res.StatusCode != http.StatusOK {
res.Body.Close()
return nil, fmt.Errorf("unexpected status code from Download %v", res.StatusCode)
}

View File

@@ -11,6 +11,7 @@ import (
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
group "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"go.opentelemetry.io/otel/trace"
@@ -218,16 +219,33 @@ func processShareEvent(ctx context.Context, ref *provider.Reference, gwc gateway
// custom logic for item trashed event
func processItemTrashedEvent(ctx context.Context, ref *provider.Reference, gwc gateway.GatewayAPIClient, initiatorid string, itemID *provider.ResourceId) ([]string, FileEvent, error) {
data := FileEvent{
ItemID: storagespace.FormatResourceID(itemID),
// TODO: check with web if parentID is needed
// ParentItemID: storagespace.FormatResourceID(*item.GetRef().GetResourceId()),
SpaceID: storagespace.FormatStorageID(itemID.GetStorageId(), itemID.GetSpaceId()),
InitiatorID: initiatorid,
resp, err := gwc.ListRecycle(ctx, &provider.ListRecycleRequest{
Ref: ref,
Key: itemID.GetOpaqueId(),
})
if err != nil {
return nil, FileEvent{}, err
}
if resp.GetStatus().GetCode() != rpc.Code_CODE_OK {
return nil, FileEvent{}, fmt.Errorf("error listing recycle: %s", resp.GetStatus().GetMessage())
}
users, err := utils.GetSpaceMembers(ctx, itemID.GetSpaceId(), gwc, utils.ViewerRole)
return users, data, err
for _, item := range resp.GetRecycleItems() {
if item.GetKey() == itemID.GetOpaqueId() {
data := FileEvent{
ItemID: storagespace.FormatResourceID(itemID),
// TODO: check with web if parentID is needed
// ParentItemID: storagespace.FormatResourceID(*item.GetRef().GetResourceId()),
SpaceID: storagespace.FormatStorageID(itemID.GetStorageId(), itemID.GetSpaceId()),
InitiatorID: initiatorid,
}
users, err := utils.GetSpaceMembers(ctx, itemID.GetSpaceId(), gwc, utils.ViewerRole)
return users, data, err
}
}
return nil, FileEvent{}, errors.New("item not found in recycle bin")
}
// adds share related data to the FileEvent

View File

@@ -83,7 +83,6 @@ func NewDriveItemPermissionsService(logger log.Logger, gatewaySelector pool.Sele
gatewaySelector: gatewaySelector,
identityCache: identityCache,
config: config,
availableRoles: unifiedrole.GetRoles(unifiedrole.RoleFilterIDs(config.UnifiedRoles.AvailableRoles...)),
},
}, nil
}

View File

@@ -441,6 +441,7 @@ var _ = Describe("DriveItemPermissionsService", func() {
})
It("returns role denied", func() {
statResponse.Info.PermissionSet = roleconversions.NewManagerRole().CS3ResourcePermissions()
cfg.UnifiedRoles.AvailableRoles = []string{unifiedrole.UnifiedRoleViewerID, unifiedrole.UnifiedRoleDeniedID, unifiedrole.UnifiedRoleManagerID}
listSharesResponse.Shares = []*collaboration.Share{
{
Id: &collaboration.ShareId{OpaqueId: "1"},
@@ -464,15 +465,11 @@ var _ = Describe("DriveItemPermissionsService", func() {
}
listPublicSharesResponse.Share = []*link.PublicShare{}
cfg = defaults.FullDefaultConfig()
cfg.UnifiedRoles.AvailableRoles = []string{unifiedrole.UnifiedRoleViewerID, unifiedrole.UnifiedRoleDeniedID, unifiedrole.UnifiedRoleManagerID}
service, err := svc.NewDriveItemPermissionsService(log.NewLogger(), gatewaySelector, cache, cfg)
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)
gatewayClient.On("ListShares", mock.Anything, mock.Anything).Return(listSharesResponse, nil)
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("ListPublicShares", mock.Anything, mock.Anything).Return(listPublicSharesResponse, nil)
permissions, err := service.ListPermissions(context.Background(), itemID, false, false)
permissions, err := driveItemPermissionsService.ListPermissions(context.Background(), itemID, false, false)
Expect(err).ToNot(HaveOccurred())
Expect(len(permissions.LibreGraphPermissionsActionsAllowedValues)).ToNot(BeZero())
Expect(len(permissions.LibreGraphPermissionsRolesAllowedValues)).ToNot(BeZero())

View File

@@ -46,7 +46,6 @@ type BaseGraphService struct {
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
identityCache identity.IdentityCache
config *config.Config
availableRoles []*libregraph.UnifiedRoleDefinition
}
func (g BaseGraphService) getSpaceRootPermissions(ctx context.Context, spaceID *storageprovider.StorageSpaceId) ([]libregraph.Permission, error) {
@@ -87,7 +86,8 @@ func (g BaseGraphService) CS3ReceivedSharesToDriveItems(ctx context.Context, rec
return nil, err
}
return cs3ReceivedSharesToDriveItems(ctx, g.logger, gatewayClient, g.identityCache, receivedShares, g.availableRoles)
availableRoles := unifiedrole.GetRoles(unifiedrole.RoleFilterIDs(g.config.UnifiedRoles.AvailableRoles...))
return cs3ReceivedSharesToDriveItems(ctx, g.logger, gatewayClient, g.identityCache, receivedShares, availableRoles)
}
func (g BaseGraphService) CS3ReceivedOCMSharesToDriveItems(ctx context.Context, receivedShares []*ocm.ReceivedShare) ([]libregraph.DriveItem, error) {
@@ -96,7 +96,8 @@ func (g BaseGraphService) CS3ReceivedOCMSharesToDriveItems(ctx context.Context,
return nil, err
}
return cs3ReceivedOCMSharesToDriveItems(ctx, g.logger, gatewayClient, g.identityCache, receivedShares, g.availableRoles)
availableRoles := unifiedrole.GetRoles(unifiedrole.RoleFilterIDs(g.config.UnifiedRoles.AvailableRoles...))
return cs3ReceivedOCMSharesToDriveItems(ctx, g.logger, gatewayClient, g.identityCache, receivedShares, availableRoles)
}
func (g BaseGraphService) cs3SpacePermissionsToLibreGraph(ctx context.Context, space *storageprovider.StorageSpace, apiVersion APIVersion) []libregraph.Permission {
@@ -195,8 +196,9 @@ func (g BaseGraphService) cs3SpacePermissionsToLibreGraph(ctx context.Context, s
p.SetExpirationDateTime(time.Unix(int64(exp.GetSeconds()), int64(exp.GetNanos())))
}
availableRoles := unifiedrole.GetRoles(unifiedrole.RoleFilterIDs(g.config.UnifiedRoles.AvailableRoles...))
if role := unifiedrole.CS3ResourcePermissionsToRole(
g.availableRoles,
availableRoles,
perm,
unifiedrole.UnifiedRoleConditionDrive,
false,
@@ -599,7 +601,7 @@ func (g BaseGraphService) cs3UserShareToPermission(ctx context.Context, share *c
perm.SetCreatedDateTime(cs3TimestampToTime(share.GetCtime()))
}
role := unifiedrole.CS3ResourcePermissionsToRole(
g.availableRoles,
unifiedrole.GetRoles(unifiedrole.RoleFilterIDs(g.config.UnifiedRoles.AvailableRoles...)),
share.GetPermissions().GetPermissions(),
roleCondition,
false,
@@ -687,8 +689,9 @@ func (g BaseGraphService) cs3OCMShareToPermission(ctx context.Context, share *oc
}
}
availableRoles := unifiedrole.GetRoles(unifiedrole.RoleFilterIDs(g.config.UnifiedRoles.AvailableRoles...))
role := unifiedrole.CS3ResourcePermissionsToRole(
g.availableRoles,
availableRoles,
permissions,
roleCondition,
true,

View File

@@ -14,7 +14,7 @@ import (
// GetRoleDefinitions a list of permission roles than can be used when sharing with users or groups
func (g Graph) GetRoleDefinitions(w http.ResponseWriter, r *http.Request) {
render.Status(r, http.StatusOK)
render.JSON(w, r, g.availableRoles)
render.JSON(w, r, unifiedrole.GetRoles(unifiedrole.RoleFilterIDs(g.config.UnifiedRoles.AvailableRoles...)))
}
// GetRoleDefinition a permission role than can be used when sharing with users or groups

View File

@@ -31,7 +31,6 @@ import (
"github.com/opencloud-eu/opencloud/services/graph/pkg/identity"
"github.com/opencloud-eu/opencloud/services/graph/pkg/identity/ldap"
graphm "github.com/opencloud-eu/opencloud/services/graph/pkg/middleware"
"github.com/opencloud-eu/opencloud/services/graph/pkg/unifiedrole"
)
const (
@@ -149,7 +148,6 @@ func NewService(opts ...Option) (Graph, error) { //nolint:maintidx
identityCache: identityCache,
gatewaySelector: options.GatewaySelector,
config: options.Config,
availableRoles: unifiedrole.GetRoles(unifiedrole.RoleFilterIDs(options.Config.UnifiedRoles.AvailableRoles...)),
},
mux: m,
specialDriveItemsCache: spacePropertiesCache,

View File

@@ -10,6 +10,7 @@ import (
libregraph "github.com/owncloud/libre-graph-api-go"
"github.com/opencloud-eu/opencloud/services/graph/pkg/errorcode"
"github.com/opencloud-eu/opencloud/services/graph/pkg/unifiedrole"
)
// ListSharedWithMe lists the files shared with the current user.
@@ -39,7 +40,8 @@ func (g Graph) listSharedWithMe(ctx context.Context) ([]libregraph.DriveItem, er
g.logger.Error().Err(err).Msg("listing shares failed")
return nil, err
}
driveItems, err := cs3ReceivedSharesToDriveItems(ctx, g.logger, gatewayClient, g.identityCache, listReceivedSharesResponse.GetShares(), g.availableRoles)
availableRoles := unifiedrole.GetRoles(unifiedrole.RoleFilterIDs(g.config.UnifiedRoles.AvailableRoles...))
driveItems, err := cs3ReceivedSharesToDriveItems(ctx, g.logger, gatewayClient, g.identityCache, listReceivedSharesResponse.GetShares(), availableRoles)
if err != nil {
g.logger.Error().Err(err).Msg("could not convert received shares to drive items")
return nil, err
@@ -51,7 +53,7 @@ func (g Graph) listSharedWithMe(ctx context.Context) ([]libregraph.DriveItem, er
g.logger.Error().Err(err).Msg("listing shares failed")
return nil, err
}
ocmDriveItems, err := cs3ReceivedOCMSharesToDriveItems(ctx, g.logger, gatewayClient, g.identityCache, listReceivedOCMSharesResponse.GetShares(), g.availableRoles)
ocmDriveItems, err := cs3ReceivedOCMSharesToDriveItems(ctx, g.logger, gatewayClient, g.identityCache, listReceivedOCMSharesResponse.GetShares(), availableRoles)
if err != nil {
g.logger.Error().Err(err).Msg("could not convert received ocm shares to drive items")
return nil, err

View File

@@ -17,16 +17,15 @@ node-generate-prod: assets
.PHONY: assets
assets: pnpm-build \
assets/identifier/static \
assets/identifier/static/favicon.svg \
assets/identifier/static/favicon.ico \
assets/identifier/static/icon-lilac.svg
assets/identifier/static:
mkdir -p assets/identifier/static
.PHONY: assets/identifier/static/favicon.svg # force overwrite
assets/identifier/static/favicon.svg:
cp src/images/favicon.svg assets/identifier/static/favicon.svg
rm assets/identifier/static/favicon.ico
.PHONY: assets/identifier/static/favicon.ico # force overwrite
assets/identifier/static/favicon.ico:
cp src/images/favicon.ico assets/identifier/static/favicon.ico
.PHONY: assets/identifier/static/icon-lilac.svg
assets/identifier/static/icon-lilac.svg:

View File

@@ -102,7 +102,7 @@
"redux-logger": "^3.0.6",
"redux-thunk": "^2.4.2",
"render-if": "^0.1.1",
"web-vitals": "^4.2.4"
"web-vitals": "^3.5.2"
},
"devDependencies": {
"@babel/core": "7.26.10",
@@ -125,7 +125,7 @@
"eslint-plugin-i18next": "^6.1.1",
"eslint-plugin-import": "^2.30.0",
"eslint-plugin-jest": "^24.7.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-jsx-a11y": "^6.9.0",
"eslint-plugin-react": "^7.37.2",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-testing-library": "^3.10.2",

View File

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#1b223d">
<link rel="icon" href="%PUBLIC_URL%/static/favicon.svg" type="image/svg+xml">
<link rel="shortcut icon" href="%PUBLIC_URL%/static/favicon.ico" type="image/x-icon">
<meta property="csp-nonce" content="__CSP_NONCE__">
<title>Sign in - OpenCloud</title>
</head>

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs" width="512" height="512"><svg id="SvgjsSvg1001" xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><rect x=".02" y="0" width="512" height="512" fill="#20434f"></rect><polygon points="255.98 342.75 271.89 333.57 271.89 267.12 329.08 234.1 329.08 215.78 313.18 206.6 255.6 239.84 198.83 207.06 182.93 216.24 182.93 234.56 240.12 267.58 240.12 333.59 255.98 342.75" fill="#e2baff"></polygon><polygon points="401.95 150.82 256 66.56 256 66.56 256 66.56 110.05 150.82 110.05 187.5 256 103.24 401.95 187.5 401.95 150.82" fill="#e2baff"></polygon><polygon points="401.95 324.5 256 408.76 110.06 324.5 110.06 361.17 256 445.43 256 445.43 256 445.43 401.95 361.17 401.95 324.5" fill="#e2baff"></polygon></svg><style>@media (prefers-color-scheme: light) { :root { filter: none; } }
@media (prefers-color-scheme: dark) { :root { filter: none; } }
</style></svg>

Before

Width:  |  Height:  |  Size: 1015 B

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.53.2. DO NOT EDIT.
// Code generated by mockery v2.53.0. DO NOT EDIT.
package mocks

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.53.2. DO NOT EDIT.
// Code generated by mockery v2.53.0. DO NOT EDIT.
package mocks

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.53.2. DO NOT EDIT.
// Code generated by mockery v2.53.0. DO NOT EDIT.
package mocks

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.53.2. DO NOT EDIT.
// Code generated by mockery v2.53.0. DO NOT EDIT.
package mocks

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.53.2. DO NOT EDIT.
// Code generated by mockery v2.53.0. DO NOT EDIT.
package mocks

View File

@@ -108,7 +108,7 @@ func ListUploadSessions(cfg *config.Config) *cli.Command {
var fsStream events.Stream
if cfg.Driver == "posix" {
// We need to init the posix driver with 'scanfs' disabled
drivers["posix"] = revaconfig.Posix(cfg, false, false)
drivers["posix"] = revaconfig.Posix(cfg, false)
// Also posix refuses to start without an events stream
fsStream, err = event.NewStream(cfg)
if err != nil {

View File

@@ -123,6 +123,7 @@ func DefaultConfig() *config.Config {
MaxConcurrency: 5,
LockCycleDurationFactor: 30,
DisableMultipart: true,
AsyncUploads: true,
},
Decomposed: config.DecomposedDriver{
Propagator: "sync",

View File

@@ -85,7 +85,7 @@ func Local(cfg *config.Config) map[string]interface{} {
}
// Posix is the config mapping for the Posix storage driver
func Posix(cfg *config.Config, enableFSScan, enableFSWatch bool) map[string]interface{} {
func Posix(cfg *config.Config, enableFSScan bool) map[string]interface{} {
return map[string]interface{}{
"root": cfg.Drivers.Posix.Root,
"personalspacepath_template": cfg.Drivers.Posix.PersonalSpacePathTemplate,
@@ -137,7 +137,7 @@ func Posix(cfg *config.Config, enableFSScan, enableFSWatch bool) map[string]inte
"use_space_groups": cfg.Drivers.Posix.UseSpaceGroups,
"enable_fs_revisions": cfg.Drivers.Posix.EnableFSRevisions,
"scan_fs": enableFSScan,
"watch_fs": enableFSWatch,
"watch_fs": cfg.Drivers.Posix.WatchFS,
"watch_type": cfg.Drivers.Posix.WatchType,
"watch_path": cfg.Drivers.Posix.WatchPath,
"watch_folder_kafka_brokers": cfg.Drivers.Posix.WatchFolderKafkaBrokers,

View File

@@ -16,7 +16,7 @@ func StorageProviderDrivers(cfg *config.Config) map[string]interface{} {
"decomposed": DecomposedNoEvents(cfg),
"s3": S3(cfg),
"decomposeds3": DecomposedS3NoEvents(cfg),
"posix": Posix(cfg, true, cfg.Drivers.Posix.WatchFS),
"posix": Posix(cfg, true),
"ocis": Decomposed(cfg), // deprecated: use decomposed
"s3ng": DecomposedS3NoEvents(cfg), // deprecated: use decomposeds3
@@ -36,7 +36,7 @@ func DataProviderDrivers(cfg *config.Config) map[string]interface{} {
"decomposed": Decomposed(cfg),
"s3": S3(cfg),
"decomposeds3": DecomposedS3(cfg),
"posix": Posix(cfg, false, false),
"posix": Posix(cfg, false),
"ocis": Decomposed(cfg), // deprecated: use decomposed
"s3ng": DecomposedS3NoEvents(cfg), // deprecated: use decomposeds3

View File

@@ -1,6 +1,6 @@
SHELL := bash
NAME := web
WEB_ASSETS_VERSION = v2.2.0
WEB_ASSETS_VERSION = v2.1.1
WEB_ASSETS_BRANCH = main
ifneq (, $(shell command -v go 2> /dev/null)) # suppress `command not found warnings` for non go targets in CI

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs" width="512" height="512"><svg id="SvgjsSvg1001" xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><rect x=".02" y="0" width="512" height="512" fill="#20434f"></rect><polygon points="255.98 342.75 271.89 333.57 271.89 267.12 329.08 234.1 329.08 215.78 313.18 206.6 255.6 239.84 198.83 207.06 182.93 216.24 182.93 234.56 240.12 267.58 240.12 333.59 255.98 342.75" fill="#e2baff"></polygon><polygon points="401.95 150.82 256 66.56 256 66.56 256 66.56 110.05 150.82 110.05 187.5 256 103.24 401.95 187.5 401.95 150.82" fill="#e2baff"></polygon><polygon points="401.95 324.5 256 408.76 110.06 324.5 110.06 361.17 256 445.43 256 445.43 256 445.43 401.95 361.17 401.95 324.5" fill="#e2baff"></polygon></svg><style>@media (prefers-color-scheme: light) { :root { filter: none; } }
@media (prefers-color-scheme: dark) { :root { filter: none; } }
</style></svg>

Before

Width:  |  Height:  |  Size: 1015 B

View File

@@ -43,7 +43,7 @@
}
},
"logo": "themes/opencloud-dev/assets/logo.svg",
"favicon": "themes/opencloud-dev/assets/favicon.svg"
"favicon": "themes/opencloud-dev/assets/favicon.jpg"
},
"themes": [
{

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs" width="512" height="512"><svg id="SvgjsSvg1001" xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><rect x=".02" y="0" width="512" height="512" fill="#20434f"></rect><polygon points="255.98 342.75 271.89 333.57 271.89 267.12 329.08 234.1 329.08 215.78 313.18 206.6 255.6 239.84 198.83 207.06 182.93 216.24 182.93 234.56 240.12 267.58 240.12 333.59 255.98 342.75" fill="#e2baff"></polygon><polygon points="401.95 150.82 256 66.56 256 66.56 256 66.56 110.05 150.82 110.05 187.5 256 103.24 401.95 187.5 401.95 150.82" fill="#e2baff"></polygon><polygon points="401.95 324.5 256 408.76 110.06 324.5 110.06 361.17 256 445.43 256 445.43 256 445.43 401.95 361.17 401.95 324.5" fill="#e2baff"></polygon></svg><style>@media (prefers-color-scheme: light) { :root { filter: none; } }
@media (prefers-color-scheme: dark) { :root { filter: none; } }
</style></svg>

Before

Width:  |  Height:  |  Size: 1015 B

View File

@@ -50,7 +50,7 @@
"web": {
"defaults": {
"logo": "themes/opencloud/assets/logo.svg",
"favicon": "themes/opencloud/assets/favicon.svg",
"favicon": "themes/opencloud/assets/favicon.ico",
"designTokens": {
"breakpoints": {
"xsmall-max": "",
@@ -94,9 +94,9 @@
"label": "Light Theme",
"designTokens": {
"roles": {
"primary": "#E2BAFF",
"primary": "#07677F",
"surfaceTint": "#07677F",
"onPrimary": "#19353F",
"onPrimary": "#FFFFFF",
"primaryContainer": "#B7EAFF",
"onPrimaryContainer": "#001F28",
"secondary": "#20434f",

View File

@@ -193,6 +193,7 @@
- [apiServiceAvailability/serviceAvailabilityCheck.feature:125](https://github.com/opencloud-eu/opencloud/blob/main/tests/acceptance/features/apiServiceAvailability/serviceAvailabilityCheck.feature#L125)
#### [Skip tests for different languages](https://github.com/opencloud-eu/opencloud/issues/183)
- [apiAntivirus/antivirus.feature:311](https://github.com/opencloud-eu/opencloud/blob/main/tests/acceptance/features/apiAntivirus/antivirus.feature#L311)
- [apiActivities/activities.feature:2598](https://github.com/opencloud-eu/opencloud/blob/main/tests/acceptance/features/apiActivities/activities.feature#L2598)

View File

@@ -308,7 +308,7 @@ Feature: antivirus
| dav-path-version | language | subject | message |
| old | es | Virus encontrado | Virus encontrado en aFileWithVirus.txt. La subida no ha sido posible. Virus: Eicar-Signature |
| new | es | Virus encontrado | Virus encontrado en aFileWithVirus.txt. La subida no ha sido posible. Virus: Eicar-Signature |
| spaces | es | Virus encontrado | Virus encontrado en aFileWithVirus.txt. La subida no ha sido posible. Virus: Eicar-Signature |
| spaces | es | Virus encontrado | Virus encontrado en aFileWithVirus.txt. La subida no ha sido posible. Eicar-Signature |
| old | de | Virus gefunden | In aFileWithVirus.txt wurde potenziell schädlicher Code gefunden. Das Hochladen wurde abgebrochen. Grund: Eicar-Signature |
| new | de | Virus gefunden | In aFileWithVirus.txt wurde potenziell schädlicher Code gefunden. Das Hochladen wurde abgebrochen. Grund: Eicar-Signature |
| spaces | de | Virus gefunden | In aFileWithVirus.txt wurde potenziell schädlicher Code gefunden. Das Hochladen wurde abgebrochen. Grund: Eicar-Signature |

View File

@@ -1,102 +0,0 @@
version: "2"
linters:
default: all
disable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- err113
- errcheck
- errchkjson
- errname
- errorlint
- exhaustive
- exhaustruct
- exptostd
- fatcontext
- forbidigo
- forcetypeassert
- funlen
- ginkgolinter
- gocheckcompilerdirectives
- gochecknoglobals
- gochecknoinits
- gochecksumtype
- gocognit
- goconst
- gocritic
- gocyclo
- godot
- godox
- goheader
- gomoddirectives
- gomodguard
- goprintffuncname
- gosec
- gosmopolitan
- govet
- grouper
- iface
- importas
- inamedparam
- ineffassign
- interfacebloat
- intrange
- ireturn
- lll
- loggercheck
- maintidx
- makezero
- mirror
- misspell
- mnd
- musttag
- nakedret
- nestif
- nilerr
- nilnesserr
- nilnil
- nlreturn
- noctx
- nolintlint
- nonamedreturns
- nosprintfhostport
- paralleltest
- perfsprint
- prealloc
- predeclared
- promlinter
- protogetter
- reassign
- recvcheck
- revive
- rowserrcheck
- sloglint
- spancheck
- sqlclosecheck
- staticcheck
- tagalign
- tagliatelle
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- unparam
- varnamelen
- whitespace
- wrapcheck
- wsl
- zerologlint

View File

@@ -3,7 +3,7 @@ GOCMD=go
linters-install:
@golangci-lint --version >/dev/null 2>&1 || { \
echo "installing linting tools..."; \
curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v2.0.2; \
curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v1.41.1; \
}
lint: linters-install

View File

@@ -1,6 +1,7 @@
Package validator
=================
<img align="right" src="logo.png">![Project status](https://img.shields.io/badge/version-10.25.0-green.svg)
<img align="right" src="logo.png">[![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
![Project status](https://img.shields.io/badge/version-10.25.0-green.svg)
[![Build Status](https://github.com/go-playground/validator/actions/workflows/workflow.yml/badge.svg)](https://github.com/go-playground/validator/actions)
[![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=master&service=github)](https://coveralls.io/github/go-playground/validator?branch=master)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator)
@@ -172,7 +173,6 @@ validate := validator.New(validator.WithRequiredStructEnabled())
| spicedb | SpiceDb ObjectID/Permission/Type |
| datetime | Datetime |
| e164 | e164 formatted phone number |
| ein | U.S. Employeer Identification Number |
| email | E-mail String
| eth_addr | Ethereum Address |
| hexadecimal | Hexadecimal String |

View File

@@ -9,7 +9,6 @@ import (
"fmt"
"io/fs"
"net"
"net/mail"
"net/url"
"os"
"reflect"
@@ -243,7 +242,6 @@ var (
"mongodb_connection_string": isMongoDBConnectionString,
"cron": isCron,
"spicedb": isSpiceDB,
"ein": isEIN,
}
)
@@ -260,7 +258,7 @@ func parseOneOfParam2(s string) []string {
oneofValsCacheRWLock.Lock()
vals = splitParamsRegex().FindAllString(s, -1)
for i := 0; i < len(vals); i++ {
vals[i] = strings.ReplaceAll(vals[i], "'", "")
vals[i] = strings.Replace(vals[i], "'", "", -1)
}
oneofValsCache[s] = vals
oneofValsCacheRWLock.Unlock()
@@ -1378,6 +1376,7 @@ func isEqIgnoreCase(fl FieldLevel) bool {
param := fl.Param()
switch field.Kind() {
case reflect.String:
return strings.EqualFold(field.String(), param)
}
@@ -1607,6 +1606,7 @@ func isImage(fl FieldLevel) bool {
case reflect.String:
filePath := field.String()
fileInfo, err := os.Stat(filePath)
if err != nil {
return false
}
@@ -1619,9 +1619,7 @@ func isImage(fl FieldLevel) bool {
if err != nil {
return false
}
defer func() {
_ = file.Close()
}()
defer file.Close()
mime, err := mimetype.DetectReader(file)
if err != nil {
@@ -1637,6 +1635,7 @@ func isImage(fl FieldLevel) bool {
// isFilePath is the validation function for validating if the current field's value is a valid file path.
func isFilePath(fl FieldLevel) bool {
var exists bool
var err error
@@ -1696,10 +1695,6 @@ func isE164(fl FieldLevel) bool {
// isEmail is the validation function for validating if the current field's value is a valid email address.
func isEmail(fl FieldLevel) bool {
_, err := mail.ParseAddress(fl.Field().String())
if err != nil {
return false
}
return emailRegex().MatchString(fl.Field().String())
}
@@ -2232,6 +2227,7 @@ func isGt(fl FieldLevel) bool {
case reflect.Struct:
if field.Type().ConvertibleTo(timeType) {
return field.Convert(timeType).Interface().(time.Time).After(time.Now().UTC())
}
}
@@ -2468,6 +2464,7 @@ func isLt(fl FieldLevel) bool {
case reflect.Struct:
if field.Type().ConvertibleTo(timeType) {
return field.Convert(timeType).Interface().(time.Time).Before(time.Now().UTC())
}
}
@@ -2647,6 +2644,7 @@ func isDir(fl FieldLevel) bool {
// isDirPath is the validation function for validating if the current field's value is a valid directory.
func isDirPath(fl FieldLevel) bool {
var exists bool
var err error
@@ -2959,12 +2957,6 @@ func isCveFormat(fl FieldLevel) bool {
// a valid dns RFC 1035 label, defined in RFC 1035.
func isDnsRFC1035LabelFormat(fl FieldLevel) bool {
val := fl.Field().String()
size := len(val)
if size > 63 {
return false
}
return dnsRegexRFC1035Label().MatchString(val)
}
@@ -3068,14 +3060,3 @@ func isCron(fl FieldLevel) bool {
cronString := fl.Field().String()
return cronRegex().MatchString(cronString)
}
// isEIN is the validation function for validating if the current field's value is a valid U.S. Employer Identification Number (EIN)
func isEIN(fl FieldLevel) bool {
field := fl.Field()
if field.Len() != 10 {
return false
}
return einRegex().MatchString(field.String())
}

View File

@@ -309,7 +309,7 @@ func (v *Validate) parseFieldTagsRecursive(tag string, fieldName string, alias s
}
if len(vals) > 1 {
current.param = strings.ReplaceAll(strings.ReplaceAll(vals[1], utf8HexComma, ","), utf8Pipe, "|")
current.param = strings.Replace(strings.Replace(vals[1], utf8HexComma, ",", -1), utf8Pipe, "|", -1)
}
}
current.isBlockEnd = true

View File

@@ -959,7 +959,7 @@ Although an empty string is a valid base64 URL safe value, this will report
an empty string as an error, if you wish to accept an empty string as valid
you can use this with the omitempty tag.
Usage: base64rawurl
Usage: base64url
# Bitcoin Address
@@ -1134,12 +1134,6 @@ This validates that a string value contains a valid longitude.
Usage: longitude
# Employeer Identification Number EIN
This validates that a string value contains a valid U.S. Employer Identification Number.
Usage: ein
# Social Security Number SSN
This validates that a string value contains a valid U.S. Social Security Number.

View File

@@ -69,7 +69,7 @@ const (
splitParamsRegexString = `'[^']*'|\S+`
bicRegexString = `^[A-Za-z]{6}[A-Za-z0-9]{2}([A-Za-z0-9]{3})?$`
semverRegexString = `^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$` // numbered capture groups https://semver.org/
dnsRegexStringRFC1035Label = "^[a-z]([-a-z0-9]*[a-z0-9])?$"
dnsRegexStringRFC1035Label = "^[a-z]([-a-z0-9]*[a-z0-9]){0,62}$"
cveRegexString = `^CVE-(1999|2\d{3})-(0[^0]\d{2}|0\d[^0]\d{1}|0\d{2}[^0]|[1-9]{1}\d{3,})$` // CVE Format Id https://cve.mitre.org/cve/identifiers/syntaxchange.html
mongodbIdRegexString = "^[a-f\\d]{24}$"
mongodbConnStringRegexString = "^mongodb(\\+srv)?:\\/\\/(([a-zA-Z\\d]+):([a-zA-Z\\d$:\\/?#\\[\\]@]+)@)?(([a-z\\d.-]+)(:[\\d]+)?)((,(([a-z\\d.-]+)(:(\\d+))?))*)?(\\/[a-zA-Z-_]{1,64})?(\\?(([a-zA-Z]+)=([a-zA-Z\\d]+))(&(([a-zA-Z\\d]+)=([a-zA-Z\\d]+))?)*)?$"
@@ -77,7 +77,6 @@ const (
spicedbIDRegexString = `^(([a-zA-Z0-9/_|\-=+]{1,})|\*)$`
spicedbPermissionRegexString = "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
spicedbTypeRegexString = "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)?[a-z][a-z0-9_]{1,62}[a-z0-9]$"
einRegexString = "^(\\d{2}-\\d{7})$"
)
func lazyRegexCompile(str string) func() *regexp.Regexp {
@@ -161,5 +160,4 @@ var (
spicedbIDRegex = lazyRegexCompile(spicedbIDRegexString)
spicedbPermissionRegex = lazyRegexCompile(spicedbPermissionRegexString)
spicedbTypeRegex = lazyRegexCompile(spicedbTypeRegexString)
einRegex = lazyRegexCompile(einRegexString)
)

View File

@@ -46,9 +46,9 @@ type StructLevel interface {
//
// NOTES:
//
// fieldName and structFieldName get appended to the existing
// namespace that validator is on. e.g. pass 'FirstName' or
// 'Names[0]' depending on the nesting
// fieldName and altName get appended to the existing namespace that
// validator is on. e.g. pass 'FirstName' or 'Names[0]' depending
// on the nesting
//
// tag can be an existing validation tag or just something you make up
// and process on the flip side it's up to you.

View File

@@ -217,18 +217,17 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
var err error
var t string
var f64 float64
var digits uint64
var kind reflect.Kind
fn := func() (err error) {
if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:]))
}
if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:]))
}
f64, err = strconv.ParseFloat(fe.Param(), 64)
return
f64, err := strconv.ParseFloat(fe.Param(), 64)
if err != nil {
goto END
}
kind = fe.Kind()
@@ -241,11 +240,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var c string
err = fn()
if err != nil {
goto END
}
c, err = ut.C("min-string-character", f64, digits, ut.FmtNumber(f64, digits))
if err != nil {
goto END
@@ -256,11 +250,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
case reflect.Slice, reflect.Map, reflect.Array:
var c string
err = fn()
if err != nil {
goto END
}
c, err = ut.C("min-items-item", f64, digits, ut.FmtNumber(f64, digits))
if err != nil {
goto END
@@ -269,16 +258,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
t, err = ut.T("min-items", fe.Field(), c)
default:
if fe.Type() == reflect.TypeOf(time.Duration(0)) {
t, err = ut.T("min-number", fe.Field(), fe.Param())
goto END
}
err = fn()
if err != nil {
goto END
}
t, err = ut.T("min-number", fe.Field(), ut.FmtNumber(f64, digits))
}
@@ -326,18 +305,17 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
var err error
var t string
var f64 float64
var digits uint64
var kind reflect.Kind
fn := func() (err error) {
if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:]))
}
if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:]))
}
f64, err = strconv.ParseFloat(fe.Param(), 64)
return
f64, err := strconv.ParseFloat(fe.Param(), 64)
if err != nil {
goto END
}
kind = fe.Kind()
@@ -350,11 +328,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var c string
err = fn()
if err != nil {
goto END
}
c, err = ut.C("max-string-character", f64, digits, ut.FmtNumber(f64, digits))
if err != nil {
goto END
@@ -365,11 +338,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
case reflect.Slice, reflect.Map, reflect.Array:
var c string
err = fn()
if err != nil {
goto END
}
c, err = ut.C("max-items-item", f64, digits, ut.FmtNumber(f64, digits))
if err != nil {
goto END
@@ -378,16 +346,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
t, err = ut.T("max-items", fe.Field(), c)
default:
if fe.Type() == reflect.TypeOf(time.Duration(0)) {
t, err = ut.T("max-number", fe.Field(), fe.Param())
goto END
}
err = fn()
if err != nil {
goto END
}
t, err = ut.T("max-number", fe.Field(), ut.FmtNumber(f64, digits))
}

View File

@@ -1,4 +1,5 @@
version: 2
# This is an example goreleaser.yaml file with some sane defaults.
# Make sure to check the documentation at http://goreleaser.com
builds:
-
@@ -26,7 +27,16 @@ builds:
archives:
-
id: cpuid
name_template: "cpuid-{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
name_template: "cpuid-{{ .Os }}_{{ .Arch }}_{{ .Version }}"
replacements:
aix: AIX
darwin: OSX
linux: Linux
windows: Windows
386: i386
amd64: x86_64
freebsd: FreeBSD
netbsd: NetBSD
format_overrides:
- goos: windows
format: zip
@@ -34,6 +44,8 @@ archives:
- LICENSE
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ .Tag }}-next"
changelog:
sort: asc
filters:
@@ -46,7 +58,7 @@ changelog:
nfpms:
-
file_name_template: "cpuid_package_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
file_name_template: "cpuid_package_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
vendor: Klaus Post
homepage: https://github.com/klauspost/cpuid
maintainer: Klaus Post <klauspost@gmail.com>
@@ -55,3 +67,8 @@ nfpms:
formats:
- deb
- rpm
replacements:
darwin: Darwin
linux: Linux
freebsd: FreeBSD
amd64: x86_64

View File

@@ -282,9 +282,7 @@ Exit Code 1
| AMXINT8 | Tile computational operations on 8-bit integers |
| AMXFP16 | Tile computational operations on FP16 numbers |
| AMXFP8 | Tile computational operations on FP8 numbers |
| AMXCOMPLEX | Tile computational operations on complex numbers |
| AMXTILE | Tile architecture |
| AMXTF32 | Matrix Multiplication of TF32 Tiles into Packed Single Precision Tile |
| APX_F | Intel APX |
| AVX | AVX functions |
| AVX10 | If set the Intel AVX10 Converged Vector ISA is supported |
@@ -482,16 +480,12 @@ Exit Code 1
| DCPOP | Data cache clean to Point of Persistence (DC CVAP) |
| EVTSTRM | Generic timer |
| FCMA | Floatin point complex number addition and multiplication |
| FHM | FMLAL and FMLSL instructions |
| FP | Single-precision and double-precision floating point |
| FPHP | Half-precision floating point |
| GPA | Generic Pointer Authentication |
| JSCVT | Javascript-style double->int convert (FJCVTZS) |
| LRCPC | Weaker release consistency (LDAPR, etc) |
| PMULL | Polynomial Multiply instructions (PMULL/PMULL2) |
| RNDR | Random Number instructions |
| TLB | Outer Shareable and TLB range maintenance instructions |
| TS | Flag manipulation instructions |
| SHA1 | SHA-1 instructions (SHA1C, etc) |
| SHA2 | SHA-2 instructions (SHA256H, etc) |
| SHA3 | SHA-3 instructions (EOR3, RAXI, XAR, BCAX) |

View File

@@ -83,8 +83,6 @@ const (
AMXINT8 // Tile computational operations on 8-bit integers
AMXFP8 // Tile computational operations on FP8 numbers
AMXTILE // Tile architecture
AMXTF32 // Tile architecture
AMXCOMPLEX // Matrix Multiplication of TF32 Tiles into Packed Single Precision Tile
APX_F // Intel APX
AVX // AVX functions
AVX10 // If set the Intel AVX10 Converged Vector ISA is supported
@@ -284,16 +282,12 @@ const (
DCPOP // Data cache clean to Point of Persistence (DC CVAP)
EVTSTRM // Generic timer
FCMA // Floatin point complex number addition and multiplication
FHM // FMLAL and FMLSL instructions
FP // Single-precision and double-precision floating point
FPHP // Half-precision floating point
GPA // Generic Pointer Authentication
JSCVT // Javascript-style double->int convert (FJCVTZS)
LRCPC // Weaker release consistency (LDAPR, etc)
PMULL // Polynomial Multiply instructions (PMULL/PMULL2)
RNDR // Random Number instructions
TLB // Outer Shareable and TLB range maintenance instructions
TS // Flag manipulation instructions
SHA1 // SHA-1 instructions (SHA1C, etc)
SHA2 // SHA-2 instructions (SHA256H, etc)
SHA3 // SHA-3 instructions (EOR3, RAXI, XAR, BCAX)
@@ -538,7 +532,7 @@ func (c CPUInfo) Ia32TscAux() uint32 {
return ecx
}
// SveLengths returns arm SVE vector and predicate lengths in bits.
// SveLengths returns arm SVE vector and predicate lengths.
// Will return 0, 0 if SVE is not enabled or otherwise unable to detect.
func (c CPUInfo) SveLengths() (vl, pl uint64) {
if !c.Has(SVE) {
@@ -1290,8 +1284,6 @@ func support() flagSet {
// CPUID.(EAX=7, ECX=1).EDX
fs.setIf(edx1&(1<<4) != 0, AVXVNNIINT8)
fs.setIf(edx1&(1<<5) != 0, AVXNECONVERT)
fs.setIf(edx1&(1<<7) != 0, AMXTF32)
fs.setIf(edx1&(1<<8) != 0, AMXCOMPLEX)
fs.setIf(edx1&(1<<10) != 0, AVXVNNIINT16)
fs.setIf(edx1&(1<<14) != 0, PREFETCHI)
fs.setIf(edx1&(1<<19) != 0, AVX10)

View File

@@ -157,10 +157,6 @@ func addInfo(c *CPUInfo, safe bool) {
// x--------------------------------------------------x
// | Name | bits | visible |
// |--------------------------------------------------|
// | RNDR | [63-60] | y |
// |--------------------------------------------------|
// | TLB | [59-56] | y |
// |--------------------------------------------------|
// | TS | [55-52] | y |
// |--------------------------------------------------|
// | FHM | [51-48] | y |
@@ -186,10 +182,12 @@ func addInfo(c *CPUInfo, safe bool) {
// | AES | [7-4] | y |
// x--------------------------------------------------x
f.setIf(instAttrReg0&(0xf<<60) != 0, RNDR)
f.setIf(instAttrReg0&(0xf<<56) != 0, TLB)
f.setIf(instAttrReg0&(0xf<<52) != 0, TS)
f.setIf(instAttrReg0&(0xf<<48) != 0, FHM)
// if instAttrReg0&(0xf<<52) != 0 {
// fmt.Println("TS")
// }
// if instAttrReg0&(0xf<<48) != 0 {
// fmt.Println("FHM")
// }
f.setIf(instAttrReg0&(0xf<<44) != 0, ASIMDDP)
f.setIf(instAttrReg0&(0xf<<40) != 0, SM4)
f.setIf(instAttrReg0&(0xf<<36) != 0, SM3)

View File

@@ -17,229 +17,223 @@ func _() {
_ = x[AMXINT8-7]
_ = x[AMXFP8-8]
_ = x[AMXTILE-9]
_ = x[AMXTF32-10]
_ = x[AMXCOMPLEX-11]
_ = x[APX_F-12]
_ = x[AVX-13]
_ = x[AVX10-14]
_ = x[AVX10_128-15]
_ = x[AVX10_256-16]
_ = x[AVX10_512-17]
_ = x[AVX2-18]
_ = x[AVX512BF16-19]
_ = x[AVX512BITALG-20]
_ = x[AVX512BW-21]
_ = x[AVX512CD-22]
_ = x[AVX512DQ-23]
_ = x[AVX512ER-24]
_ = x[AVX512F-25]
_ = x[AVX512FP16-26]
_ = x[AVX512IFMA-27]
_ = x[AVX512PF-28]
_ = x[AVX512VBMI-29]
_ = x[AVX512VBMI2-30]
_ = x[AVX512VL-31]
_ = x[AVX512VNNI-32]
_ = x[AVX512VP2INTERSECT-33]
_ = x[AVX512VPOPCNTDQ-34]
_ = x[AVXIFMA-35]
_ = x[AVXNECONVERT-36]
_ = x[AVXSLOW-37]
_ = x[AVXVNNI-38]
_ = x[AVXVNNIINT8-39]
_ = x[AVXVNNIINT16-40]
_ = x[BHI_CTRL-41]
_ = x[BMI1-42]
_ = x[BMI2-43]
_ = x[CETIBT-44]
_ = x[CETSS-45]
_ = x[CLDEMOTE-46]
_ = x[CLMUL-47]
_ = x[CLZERO-48]
_ = x[CMOV-49]
_ = x[CMPCCXADD-50]
_ = x[CMPSB_SCADBS_SHORT-51]
_ = x[CMPXCHG8-52]
_ = x[CPBOOST-53]
_ = x[CPPC-54]
_ = x[CX16-55]
_ = x[EFER_LMSLE_UNS-56]
_ = x[ENQCMD-57]
_ = x[ERMS-58]
_ = x[F16C-59]
_ = x[FLUSH_L1D-60]
_ = x[FMA3-61]
_ = x[FMA4-62]
_ = x[FP128-63]
_ = x[FP256-64]
_ = x[FSRM-65]
_ = x[FXSR-66]
_ = x[FXSROPT-67]
_ = x[GFNI-68]
_ = x[HLE-69]
_ = x[HRESET-70]
_ = x[HTT-71]
_ = x[HWA-72]
_ = x[HYBRID_CPU-73]
_ = x[HYPERVISOR-74]
_ = x[IA32_ARCH_CAP-75]
_ = x[IA32_CORE_CAP-76]
_ = x[IBPB-77]
_ = x[IBPB_BRTYPE-78]
_ = x[IBRS-79]
_ = x[IBRS_PREFERRED-80]
_ = x[IBRS_PROVIDES_SMP-81]
_ = x[IBS-82]
_ = x[IBSBRNTRGT-83]
_ = x[IBSFETCHSAM-84]
_ = x[IBSFFV-85]
_ = x[IBSOPCNT-86]
_ = x[IBSOPCNTEXT-87]
_ = x[IBSOPSAM-88]
_ = x[IBSRDWROPCNT-89]
_ = x[IBSRIPINVALIDCHK-90]
_ = x[IBS_FETCH_CTLX-91]
_ = x[IBS_OPDATA4-92]
_ = x[IBS_OPFUSE-93]
_ = x[IBS_PREVENTHOST-94]
_ = x[IBS_ZEN4-95]
_ = x[IDPRED_CTRL-96]
_ = x[INT_WBINVD-97]
_ = x[INVLPGB-98]
_ = x[KEYLOCKER-99]
_ = x[KEYLOCKERW-100]
_ = x[LAHF-101]
_ = x[LAM-102]
_ = x[LBRVIRT-103]
_ = x[LZCNT-104]
_ = x[MCAOVERFLOW-105]
_ = x[MCDT_NO-106]
_ = x[MCOMMIT-107]
_ = x[MD_CLEAR-108]
_ = x[MMX-109]
_ = x[MMXEXT-110]
_ = x[MOVBE-111]
_ = x[MOVDIR64B-112]
_ = x[MOVDIRI-113]
_ = x[MOVSB_ZL-114]
_ = x[MOVU-115]
_ = x[MPX-116]
_ = x[MSRIRC-117]
_ = x[MSRLIST-118]
_ = x[MSR_PAGEFLUSH-119]
_ = x[NRIPS-120]
_ = x[NX-121]
_ = x[OSXSAVE-122]
_ = x[PCONFIG-123]
_ = x[POPCNT-124]
_ = x[PPIN-125]
_ = x[PREFETCHI-126]
_ = x[PSFD-127]
_ = x[RDPRU-128]
_ = x[RDRAND-129]
_ = x[RDSEED-130]
_ = x[RDTSCP-131]
_ = x[RRSBA_CTRL-132]
_ = x[RTM-133]
_ = x[RTM_ALWAYS_ABORT-134]
_ = x[SBPB-135]
_ = x[SERIALIZE-136]
_ = x[SEV-137]
_ = x[SEV_64BIT-138]
_ = x[SEV_ALTERNATIVE-139]
_ = x[SEV_DEBUGSWAP-140]
_ = x[SEV_ES-141]
_ = x[SEV_RESTRICTED-142]
_ = x[SEV_SNP-143]
_ = x[SGX-144]
_ = x[SGXLC-145]
_ = x[SHA-146]
_ = x[SME-147]
_ = x[SME_COHERENT-148]
_ = x[SPEC_CTRL_SSBD-149]
_ = x[SRBDS_CTRL-150]
_ = x[SRSO_MSR_FIX-151]
_ = x[SRSO_NO-152]
_ = x[SRSO_USER_KERNEL_NO-153]
_ = x[SSE-154]
_ = x[SSE2-155]
_ = x[SSE3-156]
_ = x[SSE4-157]
_ = x[SSE42-158]
_ = x[SSE4A-159]
_ = x[SSSE3-160]
_ = x[STIBP-161]
_ = x[STIBP_ALWAYSON-162]
_ = x[STOSB_SHORT-163]
_ = x[SUCCOR-164]
_ = x[SVM-165]
_ = x[SVMDA-166]
_ = x[SVMFBASID-167]
_ = x[SVML-168]
_ = x[SVMNP-169]
_ = x[SVMPF-170]
_ = x[SVMPFT-171]
_ = x[SYSCALL-172]
_ = x[SYSEE-173]
_ = x[TBM-174]
_ = x[TDX_GUEST-175]
_ = x[TLB_FLUSH_NESTED-176]
_ = x[TME-177]
_ = x[TOPEXT-178]
_ = x[TSCRATEMSR-179]
_ = x[TSXLDTRK-180]
_ = x[VAES-181]
_ = x[VMCBCLEAN-182]
_ = x[VMPL-183]
_ = x[VMSA_REGPROT-184]
_ = x[VMX-185]
_ = x[VPCLMULQDQ-186]
_ = x[VTE-187]
_ = x[WAITPKG-188]
_ = x[WBNOINVD-189]
_ = x[WRMSRNS-190]
_ = x[X87-191]
_ = x[XGETBV1-192]
_ = x[XOP-193]
_ = x[XSAVE-194]
_ = x[XSAVEC-195]
_ = x[XSAVEOPT-196]
_ = x[XSAVES-197]
_ = x[AESARM-198]
_ = x[ARMCPUID-199]
_ = x[ASIMD-200]
_ = x[ASIMDDP-201]
_ = x[ASIMDHP-202]
_ = x[ASIMDRDM-203]
_ = x[ATOMICS-204]
_ = x[CRC32-205]
_ = x[DCPOP-206]
_ = x[EVTSTRM-207]
_ = x[FCMA-208]
_ = x[FHM-209]
_ = x[FP-210]
_ = x[FPHP-211]
_ = x[GPA-212]
_ = x[JSCVT-213]
_ = x[LRCPC-214]
_ = x[PMULL-215]
_ = x[RNDR-216]
_ = x[TLB-217]
_ = x[TS-218]
_ = x[SHA1-219]
_ = x[SHA2-220]
_ = x[SHA3-221]
_ = x[SHA512-222]
_ = x[SM3-223]
_ = x[SM4-224]
_ = x[SVE-225]
_ = x[lastID-226]
_ = x[APX_F-10]
_ = x[AVX-11]
_ = x[AVX10-12]
_ = x[AVX10_128-13]
_ = x[AVX10_256-14]
_ = x[AVX10_512-15]
_ = x[AVX2-16]
_ = x[AVX512BF16-17]
_ = x[AVX512BITALG-18]
_ = x[AVX512BW-19]
_ = x[AVX512CD-20]
_ = x[AVX512DQ-21]
_ = x[AVX512ER-22]
_ = x[AVX512F-23]
_ = x[AVX512FP16-24]
_ = x[AVX512IFMA-25]
_ = x[AVX512PF-26]
_ = x[AVX512VBMI-27]
_ = x[AVX512VBMI2-28]
_ = x[AVX512VL-29]
_ = x[AVX512VNNI-30]
_ = x[AVX512VP2INTERSECT-31]
_ = x[AVX512VPOPCNTDQ-32]
_ = x[AVXIFMA-33]
_ = x[AVXNECONVERT-34]
_ = x[AVXSLOW-35]
_ = x[AVXVNNI-36]
_ = x[AVXVNNIINT8-37]
_ = x[AVXVNNIINT16-38]
_ = x[BHI_CTRL-39]
_ = x[BMI1-40]
_ = x[BMI2-41]
_ = x[CETIBT-42]
_ = x[CETSS-43]
_ = x[CLDEMOTE-44]
_ = x[CLMUL-45]
_ = x[CLZERO-46]
_ = x[CMOV-47]
_ = x[CMPCCXADD-48]
_ = x[CMPSB_SCADBS_SHORT-49]
_ = x[CMPXCHG8-50]
_ = x[CPBOOST-51]
_ = x[CPPC-52]
_ = x[CX16-53]
_ = x[EFER_LMSLE_UNS-54]
_ = x[ENQCMD-55]
_ = x[ERMS-56]
_ = x[F16C-57]
_ = x[FLUSH_L1D-58]
_ = x[FMA3-59]
_ = x[FMA4-60]
_ = x[FP128-61]
_ = x[FP256-62]
_ = x[FSRM-63]
_ = x[FXSR-64]
_ = x[FXSROPT-65]
_ = x[GFNI-66]
_ = x[HLE-67]
_ = x[HRESET-68]
_ = x[HTT-69]
_ = x[HWA-70]
_ = x[HYBRID_CPU-71]
_ = x[HYPERVISOR-72]
_ = x[IA32_ARCH_CAP-73]
_ = x[IA32_CORE_CAP-74]
_ = x[IBPB-75]
_ = x[IBPB_BRTYPE-76]
_ = x[IBRS-77]
_ = x[IBRS_PREFERRED-78]
_ = x[IBRS_PROVIDES_SMP-79]
_ = x[IBS-80]
_ = x[IBSBRNTRGT-81]
_ = x[IBSFETCHSAM-82]
_ = x[IBSFFV-83]
_ = x[IBSOPCNT-84]
_ = x[IBSOPCNTEXT-85]
_ = x[IBSOPSAM-86]
_ = x[IBSRDWROPCNT-87]
_ = x[IBSRIPINVALIDCHK-88]
_ = x[IBS_FETCH_CTLX-89]
_ = x[IBS_OPDATA4-90]
_ = x[IBS_OPFUSE-91]
_ = x[IBS_PREVENTHOST-92]
_ = x[IBS_ZEN4-93]
_ = x[IDPRED_CTRL-94]
_ = x[INT_WBINVD-95]
_ = x[INVLPGB-96]
_ = x[KEYLOCKER-97]
_ = x[KEYLOCKERW-98]
_ = x[LAHF-99]
_ = x[LAM-100]
_ = x[LBRVIRT-101]
_ = x[LZCNT-102]
_ = x[MCAOVERFLOW-103]
_ = x[MCDT_NO-104]
_ = x[MCOMMIT-105]
_ = x[MD_CLEAR-106]
_ = x[MMX-107]
_ = x[MMXEXT-108]
_ = x[MOVBE-109]
_ = x[MOVDIR64B-110]
_ = x[MOVDIRI-111]
_ = x[MOVSB_ZL-112]
_ = x[MOVU-113]
_ = x[MPX-114]
_ = x[MSRIRC-115]
_ = x[MSRLIST-116]
_ = x[MSR_PAGEFLUSH-117]
_ = x[NRIPS-118]
_ = x[NX-119]
_ = x[OSXSAVE-120]
_ = x[PCONFIG-121]
_ = x[POPCNT-122]
_ = x[PPIN-123]
_ = x[PREFETCHI-124]
_ = x[PSFD-125]
_ = x[RDPRU-126]
_ = x[RDRAND-127]
_ = x[RDSEED-128]
_ = x[RDTSCP-129]
_ = x[RRSBA_CTRL-130]
_ = x[RTM-131]
_ = x[RTM_ALWAYS_ABORT-132]
_ = x[SBPB-133]
_ = x[SERIALIZE-134]
_ = x[SEV-135]
_ = x[SEV_64BIT-136]
_ = x[SEV_ALTERNATIVE-137]
_ = x[SEV_DEBUGSWAP-138]
_ = x[SEV_ES-139]
_ = x[SEV_RESTRICTED-140]
_ = x[SEV_SNP-141]
_ = x[SGX-142]
_ = x[SGXLC-143]
_ = x[SHA-144]
_ = x[SME-145]
_ = x[SME_COHERENT-146]
_ = x[SPEC_CTRL_SSBD-147]
_ = x[SRBDS_CTRL-148]
_ = x[SRSO_MSR_FIX-149]
_ = x[SRSO_NO-150]
_ = x[SRSO_USER_KERNEL_NO-151]
_ = x[SSE-152]
_ = x[SSE2-153]
_ = x[SSE3-154]
_ = x[SSE4-155]
_ = x[SSE42-156]
_ = x[SSE4A-157]
_ = x[SSSE3-158]
_ = x[STIBP-159]
_ = x[STIBP_ALWAYSON-160]
_ = x[STOSB_SHORT-161]
_ = x[SUCCOR-162]
_ = x[SVM-163]
_ = x[SVMDA-164]
_ = x[SVMFBASID-165]
_ = x[SVML-166]
_ = x[SVMNP-167]
_ = x[SVMPF-168]
_ = x[SVMPFT-169]
_ = x[SYSCALL-170]
_ = x[SYSEE-171]
_ = x[TBM-172]
_ = x[TDX_GUEST-173]
_ = x[TLB_FLUSH_NESTED-174]
_ = x[TME-175]
_ = x[TOPEXT-176]
_ = x[TSCRATEMSR-177]
_ = x[TSXLDTRK-178]
_ = x[VAES-179]
_ = x[VMCBCLEAN-180]
_ = x[VMPL-181]
_ = x[VMSA_REGPROT-182]
_ = x[VMX-183]
_ = x[VPCLMULQDQ-184]
_ = x[VTE-185]
_ = x[WAITPKG-186]
_ = x[WBNOINVD-187]
_ = x[WRMSRNS-188]
_ = x[X87-189]
_ = x[XGETBV1-190]
_ = x[XOP-191]
_ = x[XSAVE-192]
_ = x[XSAVEC-193]
_ = x[XSAVEOPT-194]
_ = x[XSAVES-195]
_ = x[AESARM-196]
_ = x[ARMCPUID-197]
_ = x[ASIMD-198]
_ = x[ASIMDDP-199]
_ = x[ASIMDHP-200]
_ = x[ASIMDRDM-201]
_ = x[ATOMICS-202]
_ = x[CRC32-203]
_ = x[DCPOP-204]
_ = x[EVTSTRM-205]
_ = x[FCMA-206]
_ = x[FP-207]
_ = x[FPHP-208]
_ = x[GPA-209]
_ = x[JSCVT-210]
_ = x[LRCPC-211]
_ = x[PMULL-212]
_ = x[SHA1-213]
_ = x[SHA2-214]
_ = x[SHA3-215]
_ = x[SHA512-216]
_ = x[SM3-217]
_ = x[SM4-218]
_ = x[SVE-219]
_ = x[lastID-220]
_ = x[firstID-0]
}
const _FeatureID_name = "firstIDADXAESNIAMD3DNOWAMD3DNOWEXTAMXBF16AMXFP16AMXINT8AMXFP8AMXTILEAMXTF32AMXCOMPLEXAPX_FAVXAVX10AVX10_128AVX10_256AVX10_512AVX2AVX512BF16AVX512BITALGAVX512BWAVX512CDAVX512DQAVX512ERAVX512FAVX512FP16AVX512IFMAAVX512PFAVX512VBMIAVX512VBMI2AVX512VLAVX512VNNIAVX512VP2INTERSECTAVX512VPOPCNTDQAVXIFMAAVXNECONVERTAVXSLOWAVXVNNIAVXVNNIINT8AVXVNNIINT16BHI_CTRLBMI1BMI2CETIBTCETSSCLDEMOTECLMULCLZEROCMOVCMPCCXADDCMPSB_SCADBS_SHORTCMPXCHG8CPBOOSTCPPCCX16EFER_LMSLE_UNSENQCMDERMSF16CFLUSH_L1DFMA3FMA4FP128FP256FSRMFXSRFXSROPTGFNIHLEHRESETHTTHWAHYBRID_CPUHYPERVISORIA32_ARCH_CAPIA32_CORE_CAPIBPBIBPB_BRTYPEIBRSIBRS_PREFERREDIBRS_PROVIDES_SMPIBSIBSBRNTRGTIBSFETCHSAMIBSFFVIBSOPCNTIBSOPCNTEXTIBSOPSAMIBSRDWROPCNTIBSRIPINVALIDCHKIBS_FETCH_CTLXIBS_OPDATA4IBS_OPFUSEIBS_PREVENTHOSTIBS_ZEN4IDPRED_CTRLINT_WBINVDINVLPGBKEYLOCKERKEYLOCKERWLAHFLAMLBRVIRTLZCNTMCAOVERFLOWMCDT_NOMCOMMITMD_CLEARMMXMMXEXTMOVBEMOVDIR64BMOVDIRIMOVSB_ZLMOVUMPXMSRIRCMSRLISTMSR_PAGEFLUSHNRIPSNXOSXSAVEPCONFIGPOPCNTPPINPREFETCHIPSFDRDPRURDRANDRDSEEDRDTSCPRRSBA_CTRLRTMRTM_ALWAYS_ABORTSBPBSERIALIZESEVSEV_64BITSEV_ALTERNATIVESEV_DEBUGSWAPSEV_ESSEV_RESTRICTEDSEV_SNPSGXSGXLCSHASMESME_COHERENTSPEC_CTRL_SSBDSRBDS_CTRLSRSO_MSR_FIXSRSO_NOSRSO_USER_KERNEL_NOSSESSE2SSE3SSE4SSE42SSE4ASSSE3STIBPSTIBP_ALWAYSONSTOSB_SHORTSUCCORSVMSVMDASVMFBASIDSVMLSVMNPSVMPFSVMPFTSYSCALLSYSEETBMTDX_GUESTTLB_FLUSH_NESTEDTMETOPEXTTSCRATEMSRTSXLDTRKVAESVMCBCLEANVMPLVMSA_REGPROTVMXVPCLMULQDQVTEWAITPKGWBNOINVDWRMSRNSX87XGETBV1XOPXSAVEXSAVECXSAVEOPTXSAVESAESARMARMCPUIDASIMDASIMDDPASIMDHPASIMDRDMATOMICSCRC32DCPOPEVTSTRMFCMAFHMFPFPHPGPAJSCVTLRCPCPMULLRNDRTLBTSSHA1SHA2SHA3SHA512SM3SM4SVElastID"
const _FeatureID_name = "firstIDADXAESNIAMD3DNOWAMD3DNOWEXTAMXBF16AMXFP16AMXINT8AMXFP8AMXTILEAPX_FAVXAVX10AVX10_128AVX10_256AVX10_512AVX2AVX512BF16AVX512BITALGAVX512BWAVX512CDAVX512DQAVX512ERAVX512FAVX512FP16AVX512IFMAAVX512PFAVX512VBMIAVX512VBMI2AVX512VLAVX512VNNIAVX512VP2INTERSECTAVX512VPOPCNTDQAVXIFMAAVXNECONVERTAVXSLOWAVXVNNIAVXVNNIINT8AVXVNNIINT16BHI_CTRLBMI1BMI2CETIBTCETSSCLDEMOTECLMULCLZEROCMOVCMPCCXADDCMPSB_SCADBS_SHORTCMPXCHG8CPBOOSTCPPCCX16EFER_LMSLE_UNSENQCMDERMSF16CFLUSH_L1DFMA3FMA4FP128FP256FSRMFXSRFXSROPTGFNIHLEHRESETHTTHWAHYBRID_CPUHYPERVISORIA32_ARCH_CAPIA32_CORE_CAPIBPBIBPB_BRTYPEIBRSIBRS_PREFERREDIBRS_PROVIDES_SMPIBSIBSBRNTRGTIBSFETCHSAMIBSFFVIBSOPCNTIBSOPCNTEXTIBSOPSAMIBSRDWROPCNTIBSRIPINVALIDCHKIBS_FETCH_CTLXIBS_OPDATA4IBS_OPFUSEIBS_PREVENTHOSTIBS_ZEN4IDPRED_CTRLINT_WBINVDINVLPGBKEYLOCKERKEYLOCKERWLAHFLAMLBRVIRTLZCNTMCAOVERFLOWMCDT_NOMCOMMITMD_CLEARMMXMMXEXTMOVBEMOVDIR64BMOVDIRIMOVSB_ZLMOVUMPXMSRIRCMSRLISTMSR_PAGEFLUSHNRIPSNXOSXSAVEPCONFIGPOPCNTPPINPREFETCHIPSFDRDPRURDRANDRDSEEDRDTSCPRRSBA_CTRLRTMRTM_ALWAYS_ABORTSBPBSERIALIZESEVSEV_64BITSEV_ALTERNATIVESEV_DEBUGSWAPSEV_ESSEV_RESTRICTEDSEV_SNPSGXSGXLCSHASMESME_COHERENTSPEC_CTRL_SSBDSRBDS_CTRLSRSO_MSR_FIXSRSO_NOSRSO_USER_KERNEL_NOSSESSE2SSE3SSE4SSE42SSE4ASSSE3STIBPSTIBP_ALWAYSONSTOSB_SHORTSUCCORSVMSVMDASVMFBASIDSVMLSVMNPSVMPFSVMPFTSYSCALLSYSEETBMTDX_GUESTTLB_FLUSH_NESTEDTMETOPEXTTSCRATEMSRTSXLDTRKVAESVMCBCLEANVMPLVMSA_REGPROTVMXVPCLMULQDQVTEWAITPKGWBNOINVDWRMSRNSX87XGETBV1XOPXSAVEXSAVECXSAVEOPTXSAVESAESARMARMCPUIDASIMDASIMDDPASIMDHPASIMDRDMATOMICSCRC32DCPOPEVTSTRMFCMAFPFPHPGPAJSCVTLRCPCPMULLSHA1SHA2SHA3SHA512SM3SM4SVElastID"
var _FeatureID_index = [...]uint16{0, 7, 10, 15, 23, 34, 41, 48, 55, 61, 68, 75, 85, 90, 93, 98, 107, 116, 125, 129, 139, 151, 159, 167, 175, 183, 190, 200, 210, 218, 228, 239, 247, 257, 275, 290, 297, 309, 316, 323, 334, 346, 354, 358, 362, 368, 373, 381, 386, 392, 396, 405, 423, 431, 438, 442, 446, 460, 466, 470, 474, 483, 487, 491, 496, 501, 505, 509, 516, 520, 523, 529, 532, 535, 545, 555, 568, 581, 585, 596, 600, 614, 631, 634, 644, 655, 661, 669, 680, 688, 700, 716, 730, 741, 751, 766, 774, 785, 795, 802, 811, 821, 825, 828, 835, 840, 851, 858, 865, 873, 876, 882, 887, 896, 903, 911, 915, 918, 924, 931, 944, 949, 951, 958, 965, 971, 975, 984, 988, 993, 999, 1005, 1011, 1021, 1024, 1040, 1044, 1053, 1056, 1065, 1080, 1093, 1099, 1113, 1120, 1123, 1128, 1131, 1134, 1146, 1160, 1170, 1182, 1189, 1208, 1211, 1215, 1219, 1223, 1228, 1233, 1238, 1243, 1257, 1268, 1274, 1277, 1282, 1291, 1295, 1300, 1305, 1311, 1318, 1323, 1326, 1335, 1351, 1354, 1360, 1370, 1378, 1382, 1391, 1395, 1407, 1410, 1420, 1423, 1430, 1438, 1445, 1448, 1455, 1458, 1463, 1469, 1477, 1483, 1489, 1497, 1502, 1509, 1516, 1524, 1531, 1536, 1541, 1548, 1552, 1555, 1557, 1561, 1564, 1569, 1574, 1579, 1583, 1586, 1588, 1592, 1596, 1600, 1606, 1609, 1612, 1615, 1621}
var _FeatureID_index = [...]uint16{0, 7, 10, 15, 23, 34, 41, 48, 55, 61, 68, 73, 76, 81, 90, 99, 108, 112, 122, 134, 142, 150, 158, 166, 173, 183, 193, 201, 211, 222, 230, 240, 258, 273, 280, 292, 299, 306, 317, 329, 337, 341, 345, 351, 356, 364, 369, 375, 379, 388, 406, 414, 421, 425, 429, 443, 449, 453, 457, 466, 470, 474, 479, 484, 488, 492, 499, 503, 506, 512, 515, 518, 528, 538, 551, 564, 568, 579, 583, 597, 614, 617, 627, 638, 644, 652, 663, 671, 683, 699, 713, 724, 734, 749, 757, 768, 778, 785, 794, 804, 808, 811, 818, 823, 834, 841, 848, 856, 859, 865, 870, 879, 886, 894, 898, 901, 907, 914, 927, 932, 934, 941, 948, 954, 958, 967, 971, 976, 982, 988, 994, 1004, 1007, 1023, 1027, 1036, 1039, 1048, 1063, 1076, 1082, 1096, 1103, 1106, 1111, 1114, 1117, 1129, 1143, 1153, 1165, 1172, 1191, 1194, 1198, 1202, 1206, 1211, 1216, 1221, 1226, 1240, 1251, 1257, 1260, 1265, 1274, 1278, 1283, 1288, 1294, 1301, 1306, 1309, 1318, 1334, 1337, 1343, 1353, 1361, 1365, 1374, 1378, 1390, 1393, 1403, 1406, 1413, 1421, 1428, 1431, 1438, 1441, 1446, 1452, 1460, 1466, 1472, 1480, 1485, 1492, 1499, 1507, 1514, 1519, 1524, 1531, 1535, 1537, 1541, 1544, 1549, 1554, 1559, 1563, 1567, 1571, 1577, 1580, 1583, 1586, 1592}
func (i FeatureID) String() string {
if i < 0 || i >= FeatureID(len(_FeatureID_index)-1) {

View File

@@ -96,11 +96,9 @@ func tryToFillCPUInfoFomSysctl(c *CPUInfo) {
setFeature(c, "hw.optional.arm.FEAT_DPB", DCPOP)
// setFeature(c, "", EVTSTRM)
setFeature(c, "hw.optional.arm.FEAT_FCMA", FCMA)
setFeature(c, "hw.optional.arm.FEAT_FHM", FHM)
setFeature(c, "hw.optional.arm.FEAT_FP", FP)
setFeature(c, "hw.optional.arm.FEAT_FP16", FPHP)
setFeature(c, "hw.optional.arm.FEAT_PAuth", GPA)
setFeature(c, "hw.optional.arm.FEAT_RNG", RNDR)
setFeature(c, "hw.optional.arm.FEAT_JSCVT", JSCVT)
setFeature(c, "hw.optional.arm.FEAT_LRCPC", LRCPC)
setFeature(c, "hw.optional.arm.FEAT_PMULL", PMULL)
@@ -108,10 +106,6 @@ func tryToFillCPUInfoFomSysctl(c *CPUInfo) {
setFeature(c, "hw.optional.arm.FEAT_SHA256", SHA2)
setFeature(c, "hw.optional.arm.FEAT_SHA3", SHA3)
setFeature(c, "hw.optional.arm.FEAT_SHA512", SHA512)
setFeature(c, "hw.optional.arm.FEAT_TLBIOS", TLB)
setFeature(c, "hw.optional.arm.FEAT_TLBIRANGE", TLB)
setFeature(c, "hw.optional.arm.FEAT_FlagM", TS)
setFeature(c, "hw.optional.arm.FEAT_FlagM2", TS)
// setFeature(c, "", SM3)
// setFeature(c, "", SM4)
setFeature(c, "hw.optional.arm.FEAT_SVE", SVE)

View File

@@ -39,80 +39,6 @@ const (
hwcap_SHA512 = 1 << 21
hwcap_SVE = 1 << 22
hwcap_ASIMDFHM = 1 << 23
hwcap_DIT = 1 << 24
hwcap_USCAT = 1 << 25
hwcap_ILRCPC = 1 << 26
hwcap_FLAGM = 1 << 27
hwcap_SSBS = 1 << 28
hwcap_SB = 1 << 29
hwcap_PACA = 1 << 30
hwcap_PACG = 1 << 31
hwcap_GCS = 1 << 32
hwcap2_DCPODP = 1 << 0
hwcap2_SVE2 = 1 << 1
hwcap2_SVEAES = 1 << 2
hwcap2_SVEPMULL = 1 << 3
hwcap2_SVEBITPERM = 1 << 4
hwcap2_SVESHA3 = 1 << 5
hwcap2_SVESM4 = 1 << 6
hwcap2_FLAGM2 = 1 << 7
hwcap2_FRINT = 1 << 8
hwcap2_SVEI8MM = 1 << 9
hwcap2_SVEF32MM = 1 << 10
hwcap2_SVEF64MM = 1 << 11
hwcap2_SVEBF16 = 1 << 12
hwcap2_I8MM = 1 << 13
hwcap2_BF16 = 1 << 14
hwcap2_DGH = 1 << 15
hwcap2_RNG = 1 << 16
hwcap2_BTI = 1 << 17
hwcap2_MTE = 1 << 18
hwcap2_ECV = 1 << 19
hwcap2_AFP = 1 << 20
hwcap2_RPRES = 1 << 21
hwcap2_MTE3 = 1 << 22
hwcap2_SME = 1 << 23
hwcap2_SME_I16I64 = 1 << 24
hwcap2_SME_F64F64 = 1 << 25
hwcap2_SME_I8I32 = 1 << 26
hwcap2_SME_F16F32 = 1 << 27
hwcap2_SME_B16F32 = 1 << 28
hwcap2_SME_F32F32 = 1 << 29
hwcap2_SME_FA64 = 1 << 30
hwcap2_WFXT = 1 << 31
hwcap2_EBF16 = 1 << 32
hwcap2_SVE_EBF16 = 1 << 33
hwcap2_CSSC = 1 << 34
hwcap2_RPRFM = 1 << 35
hwcap2_SVE2P1 = 1 << 36
hwcap2_SME2 = 1 << 37
hwcap2_SME2P1 = 1 << 38
hwcap2_SME_I16I32 = 1 << 39
hwcap2_SME_BI32I32 = 1 << 40
hwcap2_SME_B16B16 = 1 << 41
hwcap2_SME_F16F16 = 1 << 42
hwcap2_MOPS = 1 << 43
hwcap2_HBC = 1 << 44
hwcap2_SVE_B16B16 = 1 << 45
hwcap2_LRCPC3 = 1 << 46
hwcap2_LSE128 = 1 << 47
hwcap2_FPMR = 1 << 48
hwcap2_LUT = 1 << 49
hwcap2_FAMINMAX = 1 << 50
hwcap2_F8CVT = 1 << 51
hwcap2_F8FMA = 1 << 52
hwcap2_F8DP4 = 1 << 53
hwcap2_F8DP2 = 1 << 54
hwcap2_F8E4M3 = 1 << 55
hwcap2_F8E5M2 = 1 << 56
hwcap2_SME_LUTV2 = 1 << 57
hwcap2_SME_F8F16 = 1 << 58
hwcap2_SME_F8F32 = 1 << 59
hwcap2_SME_SF8FMA = 1 << 60
hwcap2_SME_SF8DP4 = 1 << 61
hwcap2_SME_SF8DP2 = 1 << 62
hwcap2_POE = 1 << 63
)
func detectOS(c *CPUInfo) bool {
@@ -178,15 +104,11 @@ func detectOS(c *CPUInfo) bool {
c.featureSet.setIf(isSet(hwcap, hwcap_DCPOP), DCPOP)
c.featureSet.setIf(isSet(hwcap, hwcap_EVTSTRM), EVTSTRM)
c.featureSet.setIf(isSet(hwcap, hwcap_FCMA), FCMA)
c.featureSet.setIf(isSet(hwcap, hwcap_ASIMDFHM), FHM)
c.featureSet.setIf(isSet(hwcap, hwcap_FP), FP)
c.featureSet.setIf(isSet(hwcap, hwcap_FPHP), FPHP)
c.featureSet.setIf(isSet(hwcap, hwcap_JSCVT), JSCVT)
c.featureSet.setIf(isSet(hwcap, hwcap_LRCPC), LRCPC)
c.featureSet.setIf(isSet(hwcap, hwcap_PMULL), PMULL)
c.featureSet.setIf(isSet(hwcap, hwcap2_RNG), RNDR)
// c.featureSet.setIf(isSet(hwcap, hwcap_), TLB)
// c.featureSet.setIf(isSet(hwcap, hwcap_), TS)
c.featureSet.setIf(isSet(hwcap, hwcap_SHA1), SHA1)
c.featureSet.setIf(isSet(hwcap, hwcap_SHA2), SHA2)
c.featureSet.setIf(isSet(hwcap, hwcap_SHA3), SHA3)

View File

@@ -35,7 +35,7 @@ This package follows the official [Golang Release Policy](https://golang.org/doc
- [Android](#android)
- [ARM](#arm)
- [Cross Compile](#cross-compile)
- [Compiling](#compiling)
- [Google Cloud Platform](#google-cloud-platform)
- [Linux](#linux)
- [Alpine](#alpine)
- [Fedora](#fedora)
@@ -70,6 +70,7 @@ This package can be installed with the `go get` command:
_go-sqlite3_ is *cgo* package.
If you want to build your app using go-sqlite3, you need gcc.
However, after you have built and installed _go-sqlite3_ with `go install github.com/mattn/go-sqlite3` (which requires gcc), you can build your app without relying on gcc in future.
***Important: because this is a `CGO` enabled package, you are required to set the environment variable `CGO_ENABLED=1` and have a `gcc` compiler present within your path.***
@@ -227,7 +228,11 @@ Steps:
Please refer to the project's [README](https://github.com/FiloSottile/homebrew-musl-cross#readme) for further information.
# Compiling
# Google Cloud Platform
Building on GCP is not possible because Google Cloud Platform does not allow `gcc` to be executed.
Please work only with compiled final binaries.
## Linux

View File

@@ -345,8 +345,7 @@ func callbackRetText(ctx *C.sqlite3_context, v reflect.Value) error {
if v.Type().Kind() != reflect.String {
return fmt.Errorf("cannot convert %s to TEXT", v.Type())
}
cstr := C.CString(v.Interface().(string))
C._sqlite3_result_text(ctx, cstr)
C._sqlite3_result_text(ctx, C.CString(v.Interface().(string)))
return nil
}

View File

@@ -381,7 +381,7 @@ type SQLiteStmt struct {
s *C.sqlite3_stmt
t string
closed bool
cls bool // True if the statement was created by SQLiteConn.Query
cls bool
}
// SQLiteResult implements sql.Result.
@@ -393,12 +393,12 @@ type SQLiteResult struct {
// SQLiteRows implements driver.Rows.
type SQLiteRows struct {
s *SQLiteStmt
nc int32 // Number of columns
cls bool // True if we need to close the parent statement in Close
nc int
cols []string
decltype []string
cls bool
closed bool
ctx context.Context // no better alternative to pass context into Next() method
closemu sync.Mutex
}
type functionInfo struct {
@@ -929,7 +929,6 @@ func (c *SQLiteConn) query(ctx context.Context, query string, args []driver.Name
s.(*SQLiteStmt).cls = true
na := s.NumInput()
if len(args)-start < na {
s.Close()
return nil, fmt.Errorf("not enough args to execute query: want %d got %d", na, len(args)-start)
}
// consume the number of arguments used in the current
@@ -2008,12 +2007,14 @@ func (s *SQLiteStmt) query(ctx context.Context, args []driver.NamedValue) (drive
rows := &SQLiteRows{
s: s,
nc: int32(C.sqlite3_column_count(s.s)),
cls: s.cls,
nc: int(C.sqlite3_column_count(s.s)),
cols: nil,
decltype: nil,
cls: s.cls,
closed: false,
ctx: ctx,
}
runtime.SetFinalizer(rows, (*SQLiteRows).Close)
return rows, nil
}
@@ -2110,28 +2111,24 @@ func (s *SQLiteStmt) Readonly() bool {
// Close the rows.
func (rc *SQLiteRows) Close() error {
rc.closemu.Lock()
defer rc.closemu.Unlock()
s := rc.s
if s == nil {
return nil
}
rc.s = nil // remove reference to SQLiteStmt
s.mu.Lock()
if s.closed {
s.mu.Unlock()
rc.s.mu.Lock()
if rc.s.closed || rc.closed {
rc.s.mu.Unlock()
return nil
}
rc.closed = true
if rc.cls {
s.mu.Unlock()
return s.Close()
rc.s.mu.Unlock()
return rc.s.Close()
}
rv := C.sqlite3_reset(s.s)
rv := C.sqlite3_reset(rc.s.s)
if rv != C.SQLITE_OK {
s.mu.Unlock()
return s.c.lastError()
rc.s.mu.Unlock()
return rc.s.c.lastError()
}
s.mu.Unlock()
rc.s.mu.Unlock()
rc.s = nil
runtime.SetFinalizer(rc, nil)
return nil
}
@@ -2139,9 +2136,9 @@ func (rc *SQLiteRows) Close() error {
func (rc *SQLiteRows) Columns() []string {
rc.s.mu.Lock()
defer rc.s.mu.Unlock()
if rc.s.s != nil && int(rc.nc) != len(rc.cols) {
if rc.s.s != nil && rc.nc != len(rc.cols) {
rc.cols = make([]string, rc.nc)
for i := 0; i < int(rc.nc); i++ {
for i := 0; i < rc.nc; i++ {
rc.cols[i] = C.GoString(C.sqlite3_column_name(rc.s.s, C.int(i)))
}
}
@@ -2151,7 +2148,7 @@ func (rc *SQLiteRows) Columns() []string {
func (rc *SQLiteRows) declTypes() []string {
if rc.s.s != nil && rc.decltype == nil {
rc.decltype = make([]string, rc.nc)
for i := 0; i < int(rc.nc); i++ {
for i := 0; i < rc.nc; i++ {
rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))))
}
}

View File

@@ -5,11 +5,7 @@
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
#include <stdio.h>
#ifndef USE_LIBSQLITE3
#include "sqlite3-binding.h"
#else
#include <sqlite3.h>
#endif
extern int unlock_notify_wait(sqlite3 *db);

View File

@@ -12,11 +12,7 @@ package sqlite3
#cgo CFLAGS: -DSQLITE_ENABLE_UNLOCK_NOTIFY
#include <stdlib.h>
#ifndef USE_LIBSQLITE3
#include "sqlite3-binding.h"
#else
#include <sqlite3.h>
#endif
extern void unlock_notify_callback(void *arg, int argc);
*/

View File

@@ -1,72 +1,27 @@
version: "2"
linters-settings:
misspell:
locale: US
linters:
disable-all: true
enable:
- durationcheck
- gocritic
- gomodguard
- govet
- ineffassign
- typecheck
- goimports
- misspell
- revive
- staticcheck
- unconvert
- govet
- ineffassign
- gosimple
- unused
- usetesting
- whitespace
settings:
misspell:
locale: US
staticcheck:
checks:
- all
- -SA1008
- -SA1019
- -SA4000
- -SA9004
- -ST1000
- -ST1005
- -ST1016
- -ST1021
- -ST1020
- -U1000
exclusions:
generated: lax
rules:
- path: (.+)\.go$
text: "empty-block:"
- path: (.+)\.go$
text: "unused-parameter:"
- path: (.+)\.go$
text: "dot-imports:"
- path: (.+)\.go$
text: "singleCaseSwitch: should rewrite switch statement to if statement"
- path: (.+)\.go$
text: "unlambda: replace"
- path: (.+)\.go$
text: "captLocal:"
- path: (.+)\.go$
text: "should have a package comment"
- path: (.+)\.go$
text: "ifElseChain:"
- path: (.+)\.go$
text: "elseif:"
- path: (.+)\.go$
text: "Error return value of"
- path: (.+)\.go$
text: "unnecessary conversion"
- path: (.+)\.go$
text: "Error return value is not checked"
- gocritic
issues:
max-issues-per-linter: 100
max-same-issues: 100
formatters:
enable:
- gofumpt
- goimports
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$
exclude-use-default: false
exclude:
# todo fix these when we get enough time.
- "singleCaseSwitch: should rewrite switch statement to if statement"
- "unlambda: replace"
- "captLocal:"
- "ifElseChain:"
- "elseif:"
- "should have a package comment"

View File

@@ -251,6 +251,7 @@ func (c *Client) ListenBucketNotification(ctx context.Context, bucketName, prefi
// Close current connection before looping further.
closeResponse(resp)
}
}(notificationInfoCh)

View File

@@ -90,7 +90,6 @@ type BucketVersioningConfiguration struct {
// Requires versioning to be enabled
ExcludedPrefixes []ExcludedPrefix `xml:",omitempty"`
ExcludeFolders bool `xml:",omitempty"`
PurgeOnDelete string `xml:",omitempty"`
}
// Various supported states

View File

@@ -135,16 +135,16 @@ func getAmzGrantACL(aCPolicy *accessControlPolicy) map[string][]string {
res := map[string][]string{}
for _, g := range grants {
switch g.Permission {
case "READ":
switch {
case g.Permission == "READ":
res["X-Amz-Grant-Read"] = append(res["X-Amz-Grant-Read"], "id="+g.Grantee.ID)
case "WRITE":
case g.Permission == "WRITE":
res["X-Amz-Grant-Write"] = append(res["X-Amz-Grant-Write"], "id="+g.Grantee.ID)
case "READ_ACP":
case g.Permission == "READ_ACP":
res["X-Amz-Grant-Read-Acp"] = append(res["X-Amz-Grant-Read-Acp"], "id="+g.Grantee.ID)
case "WRITE_ACP":
case g.Permission == "WRITE_ACP":
res["X-Amz-Grant-Write-Acp"] = append(res["X-Amz-Grant-Write-Acp"], "id="+g.Grantee.ID)
case "FULL_CONTROL":
case g.Permission == "FULL_CONTROL":
res["X-Amz-Grant-Full-Control"] = append(res["X-Amz-Grant-Full-Control"], "id="+g.Grantee.ID)
}
}

View File

@@ -524,6 +524,7 @@ func (c *Client) listObjectVersions(ctx context.Context, bucketName string, opts
}
return
}
}
}(resultCh)
return resultCh

View File

@@ -350,6 +350,7 @@ func (c *Client) putObjectMultipartStreamOptionalChecksum(ctx context.Context, b
// Part number always starts with '1'.
var partNumber int
for partNumber = 1; partNumber <= totalPartsCount; partNumber++ {
// Proceed to upload the part.
if partNumber == totalPartsCount {
partSize = lastPartSize

View File

@@ -392,7 +392,10 @@ func (c *Client) removeObjects(ctx context.Context, bucketName string, objectsCh
defer close(resultCh)
// Loop over entries by 1000 and call MultiDelete requests
for !finish {
for {
if finish {
break
}
count := 0
var batch []ObjectInfo

View File

@@ -194,6 +194,7 @@ func (l *ListVersionsResult) UnmarshalXML(d *xml.Decoder, _ xml.StartElement) (e
default:
return errors.New("unrecognized option:" + tagName)
}
}
}
return nil

View File

@@ -609,6 +609,7 @@ func (s *SelectResults) start(pipeWriter *io.PipeWriter) {
closeResponse(s.resp)
return
}
}
}()
}
@@ -668,6 +669,7 @@ func extractHeader(body io.Reader, myHeaders http.Header) error {
}
myHeaders.Set(headerTypeName, headerValueName)
}
return nil
}

View File

@@ -155,7 +155,7 @@ type Options struct {
// Global constants.
const (
libraryName = "minio-go"
libraryVersion = "v7.0.89"
libraryVersion = "v7.0.88"
)
// User Agent should always following the below style.
@@ -598,7 +598,7 @@ func (c *Client) do(req *http.Request) (resp *http.Response, err error) {
// If trace is enabled, dump http request and response,
// except when the traceErrorsOnly enabled and the response's status code is ok
if c.isTraceEnabled && (!c.traceErrorsOnly || resp.StatusCode != http.StatusOK) {
if c.isTraceEnabled && !(c.traceErrorsOnly && resp.StatusCode == http.StatusOK) {
err = c.dumpHTTP(req, resp)
if err != nil {
return nil, err

View File

@@ -104,8 +104,6 @@ type STSAssumeRoleOptions struct {
RoleARN string
RoleSessionName string
ExternalID string
TokenRevokeType string // Optional, used for token revokation (MinIO only extension)
}
// NewSTSAssumeRole returns a pointer to a new
@@ -163,9 +161,6 @@ func getAssumeRoleCredentials(clnt *http.Client, endpoint string, opts STSAssume
if opts.ExternalID != "" {
v.Set("ExternalId", opts.ExternalID)
}
if opts.TokenRevokeType != "" {
v.Set("TokenRevokeType", opts.TokenRevokeType)
}
u, err := url.Parse(endpoint)
if err != nil {

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