Compare commits

..

1 Commits

Author SHA1 Message Date
Viktor Scharf
ffd5c042ae replace CI images 2026-01-05 14:00:47 +01:00
293 changed files with 2362 additions and 3174 deletions

View File

@@ -15,16 +15,16 @@ OPEN_SEARCH = "opensearchproject/opensearch:2"
INBUCKET_INBUCKET = "inbucket/inbucket" INBUCKET_INBUCKET = "inbucket/inbucket"
MINIO_MC = "minio/mc:RELEASE.2021-10-07T04-19-58Z" MINIO_MC = "minio/mc:RELEASE.2021-10-07T04-19-58Z"
OC_CI_ALPINE = "owncloudci/alpine:latest" OC_CI_ALPINE = "owncloudci/alpine:latest"
OC_CI_BAZEL_BUILDIFIER = "owncloudci/bazel-buildifier:latest" OC_CI_BAZEL_BUILDIFIER = "scharfvi/bazel-buildifier:latest"
OC_CI_CLAMAVD = "owncloudci/clamavd" OC_CI_CLAMAVD = "owncloudci/clamavd"
OC_CI_DRONE_ANSIBLE = "owncloudci/drone-ansible:latest" OC_CI_DRONE_ANSIBLE = "owncloudci/drone-ansible:latest"
OC_CI_GOLANG = "registry.heinlein.group/opencloud/golang-ci:1.25" OC_CI_GOLANG = "quay.io/opencloudeu/golang-ci:1.25"
OC_CI_NODEJS = "owncloudci/nodejs:%s" OC_CI_NODEJS = "scharfvi/nodeci:24"
OC_CI_PHP = "owncloudci/php:%s" OC_CI_NODEJS_ALPINE = "scharfvi/nodeci-alpine:24"
OC_CI_WAIT_FOR = "owncloudci/wait-for:latest" OC_CI_PHP = "scharfvi/php-alpine-ci:%s"
OC_CI_WAIT_FOR = "scharfvi/wait-for:latest"
OC_CS3_API_VALIDATOR = "opencloudeu/cs3api-validator:latest" OC_CS3_API_VALIDATOR = "opencloudeu/cs3api-validator:latest"
OC_LITMUS = "owncloudci/litmus:latest" OC_LITMUS = "owncloudci/litmus:latest"
OC_UBUNTU = "owncloud/ubuntu:20.04"
ONLYOFFICE_DOCUMENT_SERVER = "onlyoffice/documentserver:7.5.1" ONLYOFFICE_DOCUMENT_SERVER = "onlyoffice/documentserver:7.5.1"
PLUGINS_DOCKER_BUILDX = "woodpeckerci/plugin-docker-buildx:latest" PLUGINS_DOCKER_BUILDX = "woodpeckerci/plugin-docker-buildx:latest"
PLUGINS_NOTATION = "registry.heinlein.group/opencloud/notation-wp-plugin:latest" PLUGINS_NOTATION = "registry.heinlein.group/opencloud/notation-wp-plugin:latest"
@@ -37,8 +37,7 @@ REDIS = "redis:6-alpine"
READY_RELEASE_GO = "woodpeckerci/plugin-ready-release-go:latest" READY_RELEASE_GO = "woodpeckerci/plugin-ready-release-go:latest"
OPENLDAP = "bitnamilegacy/openldap:2.6" OPENLDAP = "bitnamilegacy/openldap:2.6"
DEFAULT_PHP_VERSION = "8.2" DEFAULT_PHP_VERSION = "8.4"
DEFAULT_NODEJS_VERSION = "20"
CACHE_S3_SERVER = "https://s3.ci.opencloud.eu" CACHE_S3_SERVER = "https://s3.ci.opencloud.eu"
@@ -307,8 +306,8 @@ config = {
"ANTIVIRUS_CLAMAV_SOCKET": "tcp://clamav:3310", "ANTIVIRUS_CLAMAV_SOCKET": "tcp://clamav:3310",
"OC_ASYNC_UPLOADS": True, "OC_ASYNC_UPLOADS": True,
"OC_ADD_RUN_SERVICES": "antivirus", "OC_ADD_RUN_SERVICES": "antivirus",
"STORAGE_USERS_DRIVER": "decomposed",
}, },
"storages": ["decomposed"],
}, },
"multiTenancy": { "multiTenancy": {
"suites": [ "suites": [
@@ -345,29 +344,16 @@ config = {
}, },
}, },
}, },
"coreApiTests": { "apiTests": {
"numberOfParts": 7, "numberOfParts": 7,
"skip": False, "skip": False,
"skipExceptParts": [], "skipExceptParts": [],
"storages": ["posix"],
}, },
"e2eTests": { "e2eTests": {
"part": { "part": {
"skip": False, "skip": False,
"totalParts": 4, # divide and run all suites in parts (divide pipelines) "totalParts": 4, # divide and run all suites in parts (divide pipelines)
# suites to skip "xsuites": ["search", "app-provider", "app-provider-onlyOffice", "app-store", "keycloak", "oidc", "ocm", "a11y", "mobile-view", "navigation"], # suites to skip
"xsuites": [
"search",
"app-provider",
"app-provider-onlyOffice",
"app-store",
"keycloak",
"oidc",
"ocm",
"a11y",
"mobile-view",
"navigation",
],
}, },
"search": { "search": {
"skip": False, "skip": False,
@@ -622,9 +608,16 @@ def testPipelines(ctx):
pipelines.append(wopiValidatorTests(ctx, storage, "cs3", "default")) pipelines.append(wopiValidatorTests(ctx, storage, "cs3", "default"))
pipelines += localApiTestPipeline(ctx) pipelines += localApiTestPipeline(ctx)
pipelines += coreApiTestPipeline(ctx)
pipelines += e2eTestPipeline(ctx) if "skip" not in config["apiTests"] or not config["apiTests"]["skip"]:
pipelines += multiServiceE2ePipeline(ctx) pipelines += apiTests(ctx)
enable_watch_fs = [False]
if ctx.build.event == "cron":
enable_watch_fs.append(True)
for run_with_watch_fs_enabled in enable_watch_fs:
pipelines += e2eTestPipeline(ctx, run_with_watch_fs_enabled) + multiServiceE2ePipeline(ctx, run_with_watch_fs_enabled)
if ("skip" not in config["k6LoadTests"] or not config["k6LoadTests"]["skip"]) and ("k6-test" in ctx.build.title.lower() or ctx.build.event == "cron"): if ("skip" not in config["k6LoadTests"] or not config["k6LoadTests"]["skip"]) and ("k6-test" in ctx.build.title.lower() or ctx.build.event == "cron"):
pipelines += k6LoadTests(ctx) pipelines += k6LoadTests(ctx)
@@ -677,7 +670,7 @@ def cacheGoBin():
}, },
{ {
"name": "archive-go-bin", "name": "archive-go-bin",
"image": OC_UBUNTU, "image": OC_CI_NODEJS,
"commands": [ "commands": [
". ./.env", ". ./.env",
"if $BIN_CACHE_FOUND; then exit 0; fi", "if $BIN_CACHE_FOUND; then exit 0; fi",
@@ -715,7 +708,7 @@ def restoreGoBinCache():
}, },
{ {
"name": "extract-go-bin-cache", "name": "extract-go-bin-cache",
"image": OC_UBUNTU, "image": OC_CI_NODEJS,
"commands": [ "commands": [
"tar -xvmf %s -C /" % dirs["gobinTarPath"], "tar -xvmf %s -C /" % dirs["gobinTarPath"],
], ],
@@ -909,7 +902,7 @@ def checkGherkinLint(ctx):
"steps": [ "steps": [
{ {
"name": "lint-feature-files", "name": "lint-feature-files",
"image": OC_CI_NODEJS % DEFAULT_NODEJS_VERSION, "image": OC_CI_NODEJS_ALPINE,
"commands": [ "commands": [
"npm install -g @gherlint/gherlint@1.1.0", "npm install -g @gherlint/gherlint@1.1.0",
"make test-gherkin-lint", "make test-gherkin-lint",
@@ -1001,6 +994,124 @@ def codestyle(ctx):
return pipelines return pipelines
def localApiTestPipeline(ctx):
pipelines = []
with_remote_php = [True]
enable_watch_fs = [False]
if ctx.build.event == "cron":
with_remote_php.append(False)
enable_watch_fs.append(True)
storages = ["posix"]
if "[decomposed]" in ctx.build.title.lower():
storages = ["decomposed"]
defaults = {
"suites": {},
"skip": False,
"extraTestEnvironment": {},
"extraServerEnvironment": {},
"storages": storages,
"accounts_hash_difficulty": 4,
"emailNeeded": False,
"antivirusNeeded": False,
"tikaNeeded": False,
"federationServer": False,
"collaborationServiceNeeded": False,
"extraCollaborationEnvironment": {},
"withRemotePhp": with_remote_php,
"enableWatchFs": enable_watch_fs,
"ldapNeeded": False,
"generateVirusFiles": False,
}
if "localApiTests" in config:
for name, matrix in config["localApiTests"].items():
if "skip" not in matrix or not matrix["skip"]:
params = {}
for item in defaults:
params[item] = matrix[item] if item in matrix else defaults[item]
for storage in params["storages"]:
for run_with_remote_php in params["withRemotePhp"]:
for run_with_watch_fs_enabled in params["enableWatchFs"]:
pipeline = {
"name": "%s-%s%s-%s%s" % ("CLI" if name.startswith("cli") else "API", name, "-withoutRemotePhp" if not run_with_remote_php else "", "decomposed" if name.startswith("cli") else storage, "-watchfs" if run_with_watch_fs_enabled else ""),
"steps": restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]) +
(tikaService() if params["tikaNeeded"] else []) +
(waitForServices("online-offices", ["collabora:9980", "onlyoffice:443", "fakeoffice:8080"]) if params["collaborationServiceNeeded"] else []) +
(waitForClamavService() if params["antivirusNeeded"] else []) +
(waitForEmailService() if params["emailNeeded"] else []) +
(ldapService() if params["ldapNeeded"] else []) +
(waitForLdapService() if params["ldapNeeded"] else []) +
opencloudServer(storage, params["accounts_hash_difficulty"], extra_server_environment = params["extraServerEnvironment"], with_wrapper = True, tika_enabled = params["tikaNeeded"], watch_fs_enabled = run_with_watch_fs_enabled) +
(opencloudServer(storage, params["accounts_hash_difficulty"], deploy_type = "federation", extra_server_environment = params["extraServerEnvironment"], watch_fs_enabled = run_with_watch_fs_enabled) 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["extraTestEnvironment"], run_with_remote_php, params["generateVirusFiles"]) +
logRequests(),
"services": (emailService() if params["emailNeeded"] else []) +
(clamavService() if params["antivirusNeeded"] else []) +
((fakeOffice() + collaboraService() + onlyofficeService()) if params["collaborationServiceNeeded"] else []),
"depends_on": getPipelineNames(buildOpencloudBinaryForTesting(ctx)),
"when": [
event["base"],
event["cron"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "acceptance-tests"),
},
},
],
}
pipelines.append(pipeline)
return pipelines
def localApiTests(name, suites, storage = "decomposed", extra_environment = {}, with_remote_php = False, generate_virus_files = False):
test_dir = "%s/tests/acceptance" % dirs["base"]
expected_failures_file = "%s/expected-failures-localAPI-on-%s-storage.md" % (test_dir, storage)
environment = {
"TEST_SERVER_URL": OC_URL,
"TEST_SERVER_FED_URL": OC_FED_URL,
"SEND_SCENARIO_LINE_REFERENCES": True,
"STORAGE_DRIVER": storage,
"BEHAT_SUITES": ",".join(suites),
"BEHAT_FILTER_TAGS": "~@skip&&~@skipOnOpencloud-%s-Storage" % storage,
"EXPECTED_FAILURES_FILE": expected_failures_file,
"UPLOAD_DELETE_WAIT_TIME": "1" if storage == "owncloud" else 0,
"OC_WRAPPER_URL": "http://%s:5200" % OC_SERVER_NAME,
"WITH_REMOTE_PHP": with_remote_php,
"COLLABORATION_SERVICE_URL": "http://wopi-fakeoffice:9300",
"OC_STORAGE_PATH": "$HOME/.opencloud/storage/users",
"USE_BEARER_TOKEN": True,
}
for item in extra_environment:
environment[item] = extra_environment[item]
commands = []
# Generate EICAR virus test files if needed
if generate_virus_files:
commands.append("chmod +x %s/tests/acceptance/scripts/generate-virus-files.sh" % dirs["base"])
commands.append("bash %s/tests/acceptance/scripts/generate-virus-files.sh" % dirs["base"])
# Merge expected failures
if not with_remote_php:
commands.append("cat %s/expected-failures-without-remotephp.md >> %s" % (test_dir, expected_failures_file))
# Run tests
commands.append("make -C %s test-acceptance-api" % (dirs["base"]))
return [{
"name": "localApiTests-%s" % name,
"image": OC_CI_PHP % DEFAULT_PHP_VERSION,
"environment": environment,
"commands": commands,
}]
def cs3ApiTests(ctx, storage, accounts_hash_difficulty = 4): def cs3ApiTests(ctx, storage, accounts_hash_difficulty = 4):
return { return {
"name": "cs3ApiTests-%s" % storage, "name": "cs3ApiTests-%s" % storage,
@@ -1145,8 +1256,62 @@ def wopiValidatorTests(ctx, storage, wopiServerType, accounts_hash_difficulty =
], ],
} }
def localApiTestPipeline(ctx): def coreApiTests(ctx, part_number = 1, number_of_parts = 1, with_remote_php = False, accounts_hash_difficulty = 4, watch_fs_enabled = False):
storage = "posix"
if "[decomposed]" in ctx.build.title.lower():
storage = "decomposed"
filterTags = "~@skipOnOpencloud-%s-Storage" % storage
test_dir = "%s/tests/acceptance" % dirs["base"]
expected_failures_file = "%s/expected-failures-API-on-%s-storage.md" % (test_dir, storage)
return {
"name": "Core-API-Tests-%s%s-%s%s" % (part_number, "-withoutRemotePhp" if not with_remote_php else "", storage, "-watchfs" if watch_fs_enabled else ""),
"steps": restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]) +
opencloudServer(storage, accounts_hash_difficulty, with_wrapper = True, watch_fs_enabled = watch_fs_enabled) +
[
{
"name": "oC10ApiTests-%s" % part_number,
"image": OC_CI_PHP % DEFAULT_PHP_VERSION,
"environment": {
"TEST_SERVER_URL": OC_URL,
"OC_REVA_DATA_ROOT": "%s" % (dirs["opencloudRevaDataRoot"] if storage == "owncloud" else ""),
"SEND_SCENARIO_LINE_REFERENCES": True,
"STORAGE_DRIVER": storage,
"BEHAT_FILTER_TAGS": filterTags,
"DIVIDE_INTO_NUM_PARTS": number_of_parts,
"RUN_PART": part_number,
"ACCEPTANCE_TEST_TYPE": "core-api",
"EXPECTED_FAILURES_FILE": expected_failures_file,
"UPLOAD_DELETE_WAIT_TIME": "1" if storage == "owncloud" else 0,
"OC_WRAPPER_URL": "http://%s:5200" % OC_SERVER_NAME,
"WITH_REMOTE_PHP": with_remote_php,
},
"commands": [
# merge the expected failures
"" if with_remote_php else "cat %s/expected-failures-without-remotephp.md >> %s" % (test_dir, expected_failures_file),
"make -C %s test-acceptance-api" % (dirs["base"]),
],
},
] +
logRequests(),
"services": redisForOCStorage(storage),
"depends_on": getPipelineNames(buildOpencloudBinaryForTesting(ctx)),
"when": [
event["base"],
event["cron"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "acceptance-tests"),
},
},
],
}
def apiTests(ctx):
pipelines = [] pipelines = []
debugParts = config["apiTests"]["skipExceptParts"]
debugPartsEnabled = (len(debugParts) != 0)
with_remote_php = [True] with_remote_php = [True]
enable_watch_fs = [False] enable_watch_fs = [False]
@@ -1155,239 +1320,19 @@ def localApiTestPipeline(ctx):
enable_watch_fs.append(True) enable_watch_fs.append(True)
defaults = { defaults = {
"suites": {},
"skip": False,
"extraTestEnvironment": {},
"extraServerEnvironment": {},
"storages": ["posix"],
"accounts_hash_difficulty": 4,
"emailNeeded": False,
"antivirusNeeded": False,
"tikaNeeded": False,
"federationServer": False,
"collaborationServiceNeeded": False,
"extraCollaborationEnvironment": {},
"withRemotePhp": with_remote_php, "withRemotePhp": with_remote_php,
"enableWatchFs": enable_watch_fs, "enableWatchFs": enable_watch_fs,
"ldapNeeded": False,
"generateVirusFiles": False,
} }
if "localApiTests" in config: for runPart in range(1, config["apiTests"]["numberOfParts"] + 1):
for name, matrix in config["localApiTests"].items(): for run_with_remote_php in defaults["withRemotePhp"]:
if "skip" not in matrix or not matrix["skip"]: for run_with_watch_fs_enabled in defaults["enableWatchFs"]:
params = {} if not debugPartsEnabled or (debugPartsEnabled and runPart in debugParts):
for item in defaults: pipelines.append(coreApiTests(ctx, runPart, config["apiTests"]["numberOfParts"], run_with_remote_php, watch_fs_enabled = run_with_watch_fs_enabled))
params[item] = matrix[item] if item in matrix else defaults[item]
# use decomposed storage if specified in the PR title
# run CLI tests only with decomposed storage
if "[decomposed]" in ctx.build.title.lower() or name.startswith("cli"):
params["storages"] = ["decomposed"]
for storage in params["storages"]:
for run_with_remote_php in params["withRemotePhp"]:
for run_with_watch_fs_enabled in params["enableWatchFs"]:
pipeline_name = "API"
if name.startswith("cli"):
pipeline_name = "CLI"
pipeline_name += "-%s" % name
if not run_with_remote_php:
pipeline_name += "-withoutRemotePhp"
pipeline_name += "-%s" % storage
if run_with_watch_fs_enabled:
pipeline_name += "-watchfs"
pipeline = {
"name": pipeline_name,
"steps": restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]) +
(tikaService() if params["tikaNeeded"] else []) +
(waitForServices("online-offices", ["collabora:9980", "onlyoffice:443", "fakeoffice:8080"]) if params["collaborationServiceNeeded"] else []) +
(waitForClamavService() if params["antivirusNeeded"] else []) +
(waitForEmailService() if params["emailNeeded"] else []) +
(ldapService() if params["ldapNeeded"] else []) +
(waitForLdapService() if params["ldapNeeded"] else []) +
opencloudServer(
storage,
params["accounts_hash_difficulty"],
extra_server_environment = params["extraServerEnvironment"],
with_wrapper = True,
tika_enabled = params["tikaNeeded"],
watch_fs_enabled = run_with_watch_fs_enabled,
) +
(opencloudServer(storage, params["accounts_hash_difficulty"], deploy_type = "federation", extra_server_environment = params["extraServerEnvironment"], watch_fs_enabled = run_with_watch_fs_enabled) 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 []) +
localApiTest(params["suites"], storage, params["extraTestEnvironment"], run_with_remote_php, params["generateVirusFiles"]) +
logRequests(),
"services": (emailService() if params["emailNeeded"] else []) +
(clamavService() if params["antivirusNeeded"] else []) +
((fakeOffice() + collaboraService() + onlyofficeService()) if params["collaborationServiceNeeded"] else []),
"depends_on": getPipelineNames(buildOpencloudBinaryForTesting(ctx)),
"when": [
event["base"],
event["cron"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "acceptance-tests"),
},
},
],
}
pipelines.append(pipeline)
return pipelines return pipelines
def localApiTest(suites, storage = "decomposed", extra_environment = {}, with_remote_php = False, generate_virus_files = False): def e2eTestPipeline(ctx, watch_fs_enabled = False):
test_dir = "%s/tests/acceptance" % dirs["base"]
expected_failures_file = "%s/expected-failures-localAPI-on-%s-storage.md" % (test_dir, storage)
environment = {
"TEST_SERVER_URL": OC_URL,
"TEST_SERVER_FED_URL": OC_FED_URL,
"SEND_SCENARIO_LINE_REFERENCES": True,
"STORAGE_DRIVER": storage,
"BEHAT_SUITES": ",".join(suites),
"BEHAT_FILTER_TAGS": "~@skip&&~@skipOnOpencloud-%s-Storage" % storage,
"EXPECTED_FAILURES_FILE": expected_failures_file,
"UPLOAD_DELETE_WAIT_TIME": "1" if storage == "owncloud" else 0,
"OC_WRAPPER_URL": "http://%s:5200" % OC_SERVER_NAME,
"WITH_REMOTE_PHP": with_remote_php,
"COLLABORATION_SERVICE_URL": "http://wopi-fakeoffice:9300",
"OC_STORAGE_PATH": "$HOME/.opencloud/storage/users",
"USE_BEARER_TOKEN": True,
}
for item in extra_environment:
environment[item] = extra_environment[item]
commands = []
# Generate EICAR virus test files if needed
if generate_virus_files:
commands.append("chmod +x %s/tests/acceptance/scripts/generate-virus-files.sh" % dirs["base"])
commands.append("bash %s/tests/acceptance/scripts/generate-virus-files.sh" % dirs["base"])
# Merge expected failures
if not with_remote_php:
commands.append("cat %s/expected-failures-without-remotephp.md >> %s" % (test_dir, expected_failures_file))
# Run tests
commands.append("make -C %s test-acceptance-api" % (dirs["base"]))
return [{
"name": "api-tests",
"image": OC_CI_PHP % DEFAULT_PHP_VERSION,
"environment": environment,
"commands": commands,
}]
def coreApiTestPipeline(ctx):
defaults = {
"withRemotePhp": [True],
"enableWatchFs": [False],
"storages": ["posix"],
"numberOfParts": 7,
"skipExceptParts": [],
"skip": False,
"accounts_hash_difficulty": 4,
}
pipelines = []
if "coreApiTests" in config:
matrix = config["coreApiTests"]
if matrix["skip"]:
return pipelines
params = {}
for item in defaults:
params[item] = matrix[item] if item in matrix else defaults[item]
# use decomposed storage if specified in the PR title
if "[decomposed]" in ctx.build.title.lower():
params["storages"] = ["decomposed"]
if ctx.build.event == "cron":
params["withRemotePhp"] = [True, False]
params["enableWatchFs"] = [True, False]
debugParts = params["skipExceptParts"]
debugPartsEnabled = (len(debugParts) != 0)
for storage in params["storages"]:
for runPart in range(1, params["numberOfParts"] + 1):
for run_with_remote_php in params["withRemotePhp"]:
for run_with_watch_fs_enabled in params["enableWatchFs"]:
if not debugPartsEnabled or (debugPartsEnabled and runPart in debugParts):
pipeline_name = "Core-API-%s" % runPart
if not run_with_remote_php:
pipeline_name += "-withoutRemotePhp"
pipeline_name += "-%s" % storage
if run_with_watch_fs_enabled:
pipeline_name += "-watchfs"
pipeline = {
"name": pipeline_name,
"steps": restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]) +
opencloudServer(
storage,
params["accounts_hash_difficulty"],
with_wrapper = True,
watch_fs_enabled = run_with_watch_fs_enabled,
) +
coreApiTest(
runPart,
params["numberOfParts"],
run_with_remote_php,
storage,
) +
logRequests(),
"services": redisForOCStorage(storage),
"depends_on": getPipelineNames(buildOpencloudBinaryForTesting(ctx)),
"when": [
event["base"],
event["cron"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "acceptance-tests"),
},
},
],
}
pipelines.append(pipeline)
return pipelines
def coreApiTest(part_number = 1, number_of_parts = 1, with_remote_php = False, storage = "posix"):
filterTags = "~@skipOnOpencloud-%s-Storage" % storage
test_dir = "%s/tests/acceptance" % dirs["base"]
expected_failures_file = "%s/expected-failures-API-on-%s-storage.md" % (test_dir, storage)
return [{
"name": "api-tests",
"image": OC_CI_PHP % DEFAULT_PHP_VERSION,
"environment": {
"TEST_SERVER_URL": OC_URL,
"OC_REVA_DATA_ROOT": "%s" % (dirs["opencloudRevaDataRoot"] if storage == "owncloud" else ""),
"SEND_SCENARIO_LINE_REFERENCES": True,
"STORAGE_DRIVER": storage,
"BEHAT_FILTER_TAGS": filterTags,
"DIVIDE_INTO_NUM_PARTS": number_of_parts,
"RUN_PART": part_number,
"ACCEPTANCE_TEST_TYPE": "core-api",
"EXPECTED_FAILURES_FILE": expected_failures_file,
"UPLOAD_DELETE_WAIT_TIME": "1" if storage == "owncloud" else 0,
"OC_WRAPPER_URL": "http://%s:5200" % OC_SERVER_NAME,
"WITH_REMOTE_PHP": with_remote_php,
},
"commands": [
# merge the expected failures
"" if with_remote_php else "cat %s/expected-failures-without-remotephp.md >> %s" % (test_dir, expected_failures_file),
"make -C %s test-acceptance-api" % (dirs["base"]),
],
}]
def e2eTestPipeline(ctx):
defaults = { defaults = {
"skip": False, "skip": False,
"suites": [], "suites": [],
@@ -1395,8 +1340,6 @@ def e2eTestPipeline(ctx):
"totalParts": 0, "totalParts": 0,
"tikaNeeded": False, "tikaNeeded": False,
"reportTracing": False, "reportTracing": False,
"enableWatchFs": [False],
"storages": ["posix"],
} }
extra_server_environment = { extra_server_environment = {
@@ -1429,6 +1372,10 @@ def e2eTestPipeline(ctx):
if ctx.build.event == "tag": if ctx.build.event == "tag":
return pipelines return pipelines
storage = "posix"
if "[decomposed]" in ctx.build.title.lower():
storage = "decomposed"
for name, suite in config["e2eTests"].items(): for name, suite in config["e2eTests"].items():
if "skip" in suite and suite["skip"]: if "skip" in suite and suite["skip"]:
continue continue
@@ -1437,12 +1384,6 @@ def e2eTestPipeline(ctx):
for item in defaults: for item in defaults:
params[item] = suite[item] if item in suite else defaults[item] params[item] = suite[item] if item in suite else defaults[item]
if ctx.build.event == "cron":
params["enableWatchFs"] = [False, True]
if "[decomposed]" in ctx.build.title.lower():
params["storages"] = ["decomposed"]
e2e_args = "" e2e_args = ""
if params["totalParts"] > 0: if params["totalParts"] > 0:
e2e_args = "--total-parts %d" % params["totalParts"] e2e_args = "--total-parts %d" % params["totalParts"]
@@ -1456,67 +1397,61 @@ def e2eTestPipeline(ctx):
if "with-tracing" in ctx.build.title.lower(): if "with-tracing" in ctx.build.title.lower():
params["reportTracing"] = True params["reportTracing"] = True
for storage in params["storages"]: steps_before = \
for watch_fs_enabled in params["enableWatchFs"]: restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBin"]) + \
steps_before = \ restoreWebCache() + \
restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBin"]) + \ restoreWebPnpmCache() + \
restoreWebCache() + \ restoreBrowsersCache() + \
restoreWebPnpmCache() + \ (tikaService() if params["tikaNeeded"] else []) + \
restoreBrowsersCache() + \ opencloudServer(storage, extra_server_environment = extra_server_environment, tika_enabled = params["tikaNeeded"], watch_fs_enabled = watch_fs_enabled)
(tikaService() if params["tikaNeeded"] else []) + \
opencloudServer(
storage,
extra_server_environment = extra_server_environment,
tika_enabled = params["tikaNeeded"],
watch_fs_enabled = watch_fs_enabled,
)
step_e2e = { step_e2e = {
"name": "e2e-tests", "name": "e2e-tests",
"image": OC_CI_NODEJS % DEFAULT_NODEJS_VERSION, "image": OC_CI_NODEJS,
"environment": { "environment": {
"OC_BASE_URL": OC_DOMAIN, "OC_BASE_URL": OC_DOMAIN,
"HEADLESS": True, "HEADLESS": True,
"RETRY": "1", "RETRY": "1",
"WEB_UI_CONFIG_FILE": "%s/%s" % (dirs["base"], dirs["opencloudConfig"]), "WEB_UI_CONFIG_FILE": "%s/%s" % (dirs["base"], dirs["opencloudConfig"]),
"LOCAL_UPLOAD_DIR": "/uploads", "LOCAL_UPLOAD_DIR": "/uploads",
"PLAYWRIGHT_BROWSERS_PATH": "%s/%s" % (dirs["base"], ".playwright"), "PLAYWRIGHT_BROWSERS_PATH": "%s/%s" % (dirs["base"], ".playwright"),
"BROWSER": "chromium", "BROWSER": "chromium",
"REPORT_TRACING": params["reportTracing"], "REPORT_TRACING": params["reportTracing"],
}, },
"commands": [ "commands": [
"cd %s/tests/e2e" % dirs["web"], "cd %s/tests/e2e" % dirs["web"],
], ],
} }
steps_after = uploadTracingResult(ctx) steps_after = uploadTracingResult(ctx)
if params["totalParts"]:
for index in range(params["totalParts"]):
run_part = index + 1
run_e2e = {}
run_e2e.update(step_e2e)
run_e2e["commands"] = [
"cd %s/tests/e2e" % dirs["web"],
"bash run-e2e.sh %s --run-part %d" % (e2e_args, run_part),
]
pipelines.append({
"name": "e2e-tests-%s-%s-%s%s" % (name, run_part, storage, "-watchfs" if watch_fs_enabled else ""),
"steps": steps_before + [run_e2e] + steps_after,
"depends_on": getPipelineNames(buildOpencloudBinaryForTesting(ctx) + buildWebCache(ctx)),
"when": e2e_trigger,
})
else:
step_e2e["commands"].append("bash run-e2e.sh %s" % e2e_args)
pipelines.append({
"name": "e2e-tests-%s-%s%s" % (name, storage, "-watchfs" if watch_fs_enabled else ""),
"steps": steps_before + [step_e2e] + steps_after,
"depends_on": getPipelineNames(buildOpencloudBinaryForTesting(ctx) + buildWebCache(ctx)),
"when": e2e_trigger,
})
if params["totalParts"]:
for index in range(params["totalParts"]):
run_part = index + 1
run_e2e = {}
run_e2e.update(step_e2e)
run_e2e["commands"] = [
"cd %s/tests/e2e" % dirs["web"],
"bash run-e2e.sh %s --run-part %d" % (e2e_args, run_part),
]
pipelines.append({
"name": "e2e-tests-%s-%s-%s%s" % (name, run_part, storage, "-watchfs" if watch_fs_enabled else ""),
"steps": steps_before + [run_e2e] + steps_after,
"depends_on": getPipelineNames(buildOpencloudBinaryForTesting(ctx) + buildWebCache(ctx)),
"when": e2e_trigger,
})
else:
step_e2e["commands"].append("bash run-e2e.sh %s" % e2e_args)
pipelines.append({
"name": "e2e-tests-%s-%s%s" % (name, storage, "-watchfs" if watch_fs_enabled else ""),
"steps": steps_before + [step_e2e] + steps_after,
"depends_on": getPipelineNames(buildOpencloudBinaryForTesting(ctx) + buildWebCache(ctx)),
"when": e2e_trigger,
})
return pipelines return pipelines
def multiServiceE2ePipeline(ctx): def multiServiceE2ePipeline(ctx, watch_fs_enabled = False):
pipelines = [] pipelines = []
defaults = { defaults = {
@@ -1525,8 +1460,6 @@ def multiServiceE2ePipeline(ctx):
"xsuites": [], "xsuites": [],
"tikaNeeded": False, "tikaNeeded": False,
"reportTracing": False, "reportTracing": False,
"enableWatchFs": [False],
"storages": ["posix"],
} }
e2e_trigger = [ e2e_trigger = [
@@ -1547,6 +1480,10 @@ def multiServiceE2ePipeline(ctx):
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 return pipelines
storage = "posix"
if "[decomposed]" in ctx.build.title.lower():
storage = "decomposed"
extra_server_environment = { extra_server_environment = {
"OC_PASSWORD_POLICY_BANNED_PASSWORDS_LIST": "%s" % dirs["bannedPasswordList"], "OC_PASSWORD_POLICY_BANNED_PASSWORDS_LIST": "%s" % dirs["bannedPasswordList"],
"OC_JWT_SECRET": "some-opencloud-jwt-secret", "OC_JWT_SECRET": "some-opencloud-jwt-secret",
@@ -1561,6 +1498,9 @@ def multiServiceE2ePipeline(ctx):
"GRAPH_AVAILABLE_ROLES": "%s" % GRAPH_AVAILABLE_ROLES, "GRAPH_AVAILABLE_ROLES": "%s" % GRAPH_AVAILABLE_ROLES,
} }
if watch_fs_enabled:
extra_server_environment["STORAGE_USERS_POSIX_WATCH_FS"] = True
storage_users_environment = { storage_users_environment = {
"OC_CORS_ALLOW_ORIGINS": "%s,https://%s:9201" % (OC_URL, OC_SERVER_NAME), "OC_CORS_ALLOW_ORIGINS": "%s,https://%s:9201" % (OC_URL, OC_SERVER_NAME),
"STORAGE_USERS_JWT_SECRET": "some-opencloud-jwt-secret", "STORAGE_USERS_JWT_SECRET": "some-opencloud-jwt-secret",
@@ -1605,12 +1545,6 @@ def multiServiceE2ePipeline(ctx):
for item in defaults: for item in defaults:
params[item] = suite[item] if item in suite else defaults[item] params[item] = suite[item] if item in suite else defaults[item]
if ctx.build.event == "cron":
params["enableWatchFs"] = [False, True]
if "[decomposed]" in ctx.build.title.lower():
params["storages"] = ["decomposed"]
e2e_args = "" e2e_args = ""
if params["suites"]: if params["suites"]:
e2e_args = "--suites %s" % ",".join(params["suites"]) e2e_args = "--suites %s" % ",".join(params["suites"])
@@ -1622,43 +1556,38 @@ def multiServiceE2ePipeline(ctx):
if "with-tracing" in ctx.build.title.lower(): if "with-tracing" in ctx.build.title.lower():
params["reportTracing"] = True params["reportTracing"] = True
for storage in params["storages"]: steps = \
for watch_fs_enabled in params["enableWatchFs"]: restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBin"]) + \
if watch_fs_enabled: restoreWebCache() + \
extra_server_environment["STORAGE_USERS_POSIX_WATCH_FS"] = True restoreWebPnpmCache() + \
restoreBrowsersCache() + \
tikaService() + \
opencloudServer(storage, extra_server_environment = extra_server_environment, tika_enabled = params["tikaNeeded"]) + \
storage_users_services + \
[{
"name": "e2e-tests",
"image": OC_CI_NODEJS,
"environment": {
"OC_BASE_URL": OC_DOMAIN,
"HEADLESS": True,
"RETRY": "1",
"REPORT_TRACING": params["reportTracing"],
"PLAYWRIGHT_BROWSERS_PATH": "%s/%s" % (dirs["base"], ".playwright"),
"BROWSER": "chromium",
},
"commands": [
"cd %s/tests/e2e" % dirs["web"],
"bash run-e2e.sh %s" % e2e_args,
],
}] + \
uploadTracingResult(ctx)
steps = \ pipelines.append({
restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBin"]) + \ "name": "e2e-tests-multi-service%s" % ("-watchfs" if watch_fs_enabled else ""),
restoreWebCache() + \ "steps": steps,
restoreWebPnpmCache() + \ "depends_on": getPipelineNames(buildOpencloudBinaryForTesting(ctx) + buildWebCache(ctx)),
restoreBrowsersCache() + \ "when": e2e_trigger,
tikaService() + \ })
opencloudServer(storage, extra_server_environment = extra_server_environment, tika_enabled = params["tikaNeeded"]) + \
storage_users_services + \
[{
"name": "e2e-tests",
"image": OC_CI_NODEJS % DEFAULT_NODEJS_VERSION,
"environment": {
"OC_BASE_URL": OC_DOMAIN,
"HEADLESS": True,
"RETRY": "1",
"REPORT_TRACING": params["reportTracing"],
"PLAYWRIGHT_BROWSERS_PATH": "%s/%s" % (dirs["base"], ".playwright"),
"BROWSER": "chromium",
},
"commands": [
"cd %s/tests/e2e" % dirs["web"],
"bash run-e2e.sh %s" % e2e_args,
],
}] + \
uploadTracingResult(ctx)
pipelines.append({
"name": "e2e-tests-multi-service%s" % ("-watchfs" if watch_fs_enabled else ""),
"steps": steps,
"depends_on": getPipelineNames(buildOpencloudBinaryForTesting(ctx) + buildWebCache(ctx)),
"when": e2e_trigger,
})
return pipelines return pipelines
def uploadTracingResult(ctx): def uploadTracingResult(ctx):
@@ -1964,14 +1893,14 @@ def licenseCheck(ctx):
"steps": restoreGoBinCache() + [ "steps": restoreGoBinCache() + [
{ {
"name": "node-check-licenses", "name": "node-check-licenses",
"image": OC_CI_NODEJS % DEFAULT_NODEJS_VERSION, "image": OC_CI_NODEJS_ALPINE,
"commands": [ "commands": [
"make ci-node-check-licenses", "make ci-node-check-licenses",
], ],
}, },
{ {
"name": "node-save-licenses", "name": "node-save-licenses",
"image": OC_CI_NODEJS % DEFAULT_NODEJS_VERSION, "image": OC_CI_NODEJS_ALPINE,
"commands": [ "commands": [
"make ci-node-save-licenses", "make ci-node-save-licenses",
], ],
@@ -2091,7 +2020,7 @@ def makeNodeGenerate(module):
return [ return [
{ {
"name": "generate nodejs", "name": "generate nodejs",
"image": OC_CI_NODEJS % DEFAULT_NODEJS_VERSION, "image": OC_CI_NODEJS,
"environment": { "environment": {
"CHROMEDRIVER_SKIP_DOWNLOAD": True, # install fails on arm and chromedriver is a test only dependency "CHROMEDRIVER_SKIP_DOWNLOAD": True, # install fails on arm and chromedriver is a test only dependency
}, },
@@ -2764,7 +2693,7 @@ def litmus(ctx, storage):
def setupForLitmus(): def setupForLitmus():
return [{ return [{
"name": "setup-for-litmus", "name": "setup-for-litmus",
"image": OC_UBUNTU, "image": OC_CI_NODEJS,
"environment": { "environment": {
"TEST_SERVER_URL": OC_URL, "TEST_SERVER_URL": OC_URL,
}, },
@@ -2779,7 +2708,7 @@ def getWoodpeckerEnvAndCheckScript(ctx):
path_to_check_script = "%s/tests/config/woodpecker/check_web_cache.sh" % dirs["base"] path_to_check_script = "%s/tests/config/woodpecker/check_web_cache.sh" % dirs["base"]
return { return {
"name": "get-woodpecker-env-and-check-script", "name": "get-woodpecker-env-and-check-script",
"image": OC_UBUNTU, "image": OC_CI_NODEJS,
"commands": [ "commands": [
"cp %s check_web_cache.sh" % path_to_check_script, "cp %s check_web_cache.sh" % path_to_check_script,
], ],
@@ -2798,7 +2727,7 @@ def checkForWebCache(name):
def cloneWeb(): def cloneWeb():
return { return {
"name": "clone-web", "name": "clone-web",
"image": OC_CI_NODEJS % DEFAULT_NODEJS_VERSION, "image": OC_CI_NODEJS_ALPINE,
"commands": [ "commands": [
". ./.woodpecker.env", ". ./.woodpecker.env",
"if $WEB_CACHE_FOUND; then exit 0; fi", "if $WEB_CACHE_FOUND; then exit 0; fi",
@@ -2815,7 +2744,7 @@ def generateWebPnpmCache(ctx):
cloneWeb(), cloneWeb(),
{ {
"name": "install-pnpm", "name": "install-pnpm",
"image": OC_CI_NODEJS % DEFAULT_NODEJS_VERSION, "image": OC_CI_NODEJS,
"commands": [ "commands": [
". ./.woodpecker.env", ". ./.woodpecker.env",
"if $WEB_CACHE_FOUND; then exit 0; fi", "if $WEB_CACHE_FOUND; then exit 0; fi",
@@ -2827,7 +2756,7 @@ def generateWebPnpmCache(ctx):
}, },
{ {
"name": "zip-pnpm", "name": "zip-pnpm",
"image": OC_CI_NODEJS % DEFAULT_NODEJS_VERSION, "image": OC_CI_NODEJS,
"commands": [ "commands": [
". ./.woodpecker.env", ". ./.woodpecker.env",
"if $WEB_CACHE_FOUND; then exit 0; fi", "if $WEB_CACHE_FOUND; then exit 0; fi",
@@ -2889,7 +2818,7 @@ def cacheBrowsers(ctx):
browser_cache_steps = [ browser_cache_steps = [
{ {
"name": "install-browsers", "name": "install-browsers",
"image": OC_CI_NODEJS % DEFAULT_NODEJS_VERSION, "image": OC_CI_NODEJS,
"environment": { "environment": {
"PLAYWRIGHT_BROWSERS_PATH": ".playwright", "PLAYWRIGHT_BROWSERS_PATH": ".playwright",
}, },
@@ -2897,7 +2826,7 @@ def cacheBrowsers(ctx):
"cd %s" % dirs["web"], "cd %s" % dirs["web"],
". ./.woodpecker.env", ". ./.woodpecker.env",
"if $BROWSER_CACHE_FOUND; then exit 0; fi", "if $BROWSER_CACHE_FOUND; then exit 0; fi",
"pnpm exec playwright install --with-deps", "pnpm exec playwright install",
"pnpm exec playwright install --list", "pnpm exec playwright install --list",
"tar -czf %s .playwright" % dirs["playwrightBrowsersArchive"], "tar -czf %s .playwright" % dirs["playwrightBrowsersArchive"],
], ],
@@ -2932,7 +2861,7 @@ def generateWebCache(ctx):
cloneWeb(), cloneWeb(),
{ {
"name": "zip-web", "name": "zip-web",
"image": OC_UBUNTU, "image": OC_CI_NODEJS,
"commands": [ "commands": [
". ./.woodpecker.env", ". ./.woodpecker.env",
"if $WEB_CACHE_FOUND; then exit 0; fi", "if $WEB_CACHE_FOUND; then exit 0; fi",
@@ -2968,7 +2897,7 @@ def restoreWebCache():
], ],
}, { }, {
"name": "unzip-web-cache", "name": "unzip-web-cache",
"image": OC_UBUNTU, "image": OC_CI_NODEJS,
"commands": [ "commands": [
"tar -xf %s -C ." % dirs["webZip"], "tar -xf %s -C ." % dirs["webZip"],
], ],
@@ -2987,7 +2916,7 @@ def restoreWebPnpmCache(extra_commands = []):
}, { }, {
# we need to install again because the node_modules are not cached # we need to install again because the node_modules are not cached
"name": "unzip-and-install-pnpm", "name": "unzip-and-install-pnpm",
"image": OC_CI_NODEJS % DEFAULT_NODEJS_VERSION, "image": OC_CI_NODEJS,
"commands": extra_commands + [ "commands": extra_commands + [
"cd %s" % dirs["web"], "cd %s" % dirs["web"],
"rm -rf .pnpm-store", "rm -rf .pnpm-store",
@@ -3013,7 +2942,7 @@ def restoreBrowsersCache():
}, },
{ {
"name": "unzip-browsers-cache", "name": "unzip-browsers-cache",
"image": OC_UBUNTU, "image": OC_CI_NODEJS,
"commands": [ "commands": [
"tar -xf /woodpecker/src/github.com/%s/webTestRunner/playwright-browsers.tar.gz -C ." % repo_slug, "tar -xf /woodpecker/src/github.com/%s/webTestRunner/playwright-browsers.tar.gz -C ." % repo_slug,
], ],
@@ -3031,7 +2960,7 @@ def waitForEmailService():
"name": "wait-for-email", "name": "wait-for-email",
"image": OC_CI_WAIT_FOR, "image": OC_CI_WAIT_FOR,
"commands": [ "commands": [
"wait-for -it email:9000 -t 600", "wait-for -host email -port 9000 -timeout 600",
], ],
}] }]
@@ -3046,7 +2975,7 @@ def waitForClamavService():
"name": "wait-for-clamav", "name": "wait-for-clamav",
"image": OC_CI_WAIT_FOR, "image": OC_CI_WAIT_FOR,
"commands": [ "commands": [
"wait-for -it clamav:3310 -t 600", "wait-for -host clamav -port 3310 -timeout 600",
], ],
}] }]
@@ -3089,7 +3018,7 @@ def waitForLdapService():
"name": "wait-for-ldap", "name": "wait-for-ldap",
"image": OC_CI_WAIT_FOR, "image": OC_CI_WAIT_FOR,
"commands": [ "commands": [
"wait-for -it ldap-server:1636 -t 600", "wait-for -host ldap-server -port 1636 -timeout 600",
], ],
}] }]
@@ -3152,7 +3081,7 @@ def tikaService():
"name": "wait-for-tika-service", "name": "wait-for-tika-service",
"image": OC_CI_WAIT_FOR, "image": OC_CI_WAIT_FOR,
"commands": [ "commands": [
"wait-for -it tika:9998 -t 300", "wait-for -host tika -port 9998 -timeout 300",
], ],
}] }]
@@ -3262,13 +3191,18 @@ def k6LoadTests(ctx):
}] }]
def waitForServices(name, services = []): def waitForServices(name, services = []):
services = ",".join(services) commands = []
for service in services:
host, port = service.split(":", 1)
commands.append(
"wait-for -host %s -port %s -timeout 300" % (host, port),
)
return [{ return [{
"name": "wait-for-%s" % name, "name": "wait-for-%s" % name,
"image": OC_CI_WAIT_FOR, "image": OC_CI_WAIT_FOR,
"commands": [ "commands": commands,
"wait-for -it %s -t 300" % services,
],
}] }]
def openCloudHealthCheck(name, services = []): def openCloudHealthCheck(name, services = []):

View File

@@ -1,40 +1,5 @@
# Changelog # Changelog
## [4.2.0](https://github.com/opencloud-eu/opencloud/releases/tag/v4.2.0) - 2026-01-06
### ❤️ Thanks to all contributors! ❤️
@ScharfViktor, @butonic, @dragonchaser, @fschade, @micbar, @rhafer, @saw-jan
### 🐛 Bug Fixes
- fix(thumbnailer): missing font panic [[#2097](https://github.com/opencloud-eu/opencloud/pull/2097)]
- Remove sub-service binary entrypoints and fix antivirus only server cmd [[#2043](https://github.com/opencloud-eu/opencloud/pull/2043)]
- fix(thumbnailer): respect image boundaries and text wrappings [[#2062](https://github.com/opencloud-eu/opencloud/pull/2062)]
- fix: cobra viper flags and env [[#2047](https://github.com/opencloud-eu/opencloud/pull/2047)]
- fix service name in suture logs [[#2052](https://github.com/opencloud-eu/opencloud/pull/2052)]
### ✅ Tests
- [tests-only] test: wait post-processing to finish for MKCOL requests [[#2092](https://github.com/opencloud-eu/opencloud/pull/2092)]
- [tests-only] test: fix API tests [[#2087](https://github.com/opencloud-eu/opencloud/pull/2087)]
- [full-ci] use graph api in the enforcePasswordPublicLink.feature [[#2050](https://github.com/opencloud-eu/opencloud/pull/2050)]
- [full-ci][tests-only] test: check last email content with retries as emails can be delayed [[#2038](https://github.com/opencloud-eu/opencloud/pull/2038)]
- skip collaborativePosix tests in CI [[#2039](https://github.com/opencloud-eu/opencloud/pull/2039)]
### 📈 Enhancement
- allow http2 connections to proxy [[#2040](https://github.com/opencloud-eu/opencloud/pull/2040)]
- migrate from urfave/cli to spf13/cobra [[#1954](https://github.com/opencloud-eu/opencloud/pull/1954)]
### 📦️ Dependencies
- build(deps): bump go.opentelemetry.io/otel/sdk from 1.38.0 to 1.39.0 [[#2069](https://github.com/opencloud-eu/opencloud/pull/2069)]
- build(deps): bump github.com/opensearch-project/opensearch-go/v4 from 4.5.0 to 4.6.0 [[#2068](https://github.com/opencloud-eu/opencloud/pull/2068)]
- build(deps): bump github.com/testcontainers/testcontainers-go/modules/opensearch from 0.39.0 to 0.40.0 [[#1967](https://github.com/opencloud-eu/opencloud/pull/1967)]
- build(deps): bump golang.org/x/net from 0.47.0 to 0.48.0 [[#2061](https://github.com/opencloud-eu/opencloud/pull/2061)]
- build(deps): bump github.com/open-policy-agent/opa from 1.10.1 to 1.11.0 [[#1930](https://github.com/opencloud-eu/opencloud/pull/1930)]
## [4.1.0](https://github.com/opencloud-eu/opencloud/releases/tag/v4.1.0) - 2025-12-15 ## [4.1.0](https://github.com/opencloud-eu/opencloud/releases/tag/v4.1.0) - 2025-12-15
### ❤️ Thanks to all contributors! ❤️ ### ❤️ Thanks to all contributors! ❤️

View File

@@ -1,8 +1,8 @@
{ {
"name": "opencloud-eu/opencloud", "name": "opencloud-eu/opencloud",
"config" : { "config": {
"platform": { "platform": {
"php": "8.2" "php": "8.4"
}, },
"vendor-dir": "./vendor-php", "vendor-dir": "./vendor-php",
"allow-plugins": { "allow-plugins": {

10
go.mod
View File

@@ -65,7 +65,7 @@ require (
github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89 github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20250724122329-41ba6b191e76 github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20250724122329-41ba6b191e76
github.com/opencloud-eu/reva/v2 v2.41.0 github.com/opencloud-eu/reva/v2 v2.41.0
github.com/opensearch-project/opensearch-go/v4 v4.6.0 github.com/opensearch-project/opensearch-go/v4 v4.5.0
github.com/orcaman/concurrent-map v1.0.0 github.com/orcaman/concurrent-map v1.0.0
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/pkg/xattr v0.4.12 github.com/pkg/xattr v0.4.12
@@ -97,11 +97,11 @@ require (
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0
go.opentelemetry.io/contrib/zpages v0.63.0 go.opentelemetry.io/contrib/zpages v0.63.0
go.opentelemetry.io/otel v1.39.0 go.opentelemetry.io/otel v1.38.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0
go.opentelemetry.io/otel/sdk v1.39.0 go.opentelemetry.io/otel/sdk v1.38.0
go.opentelemetry.io/otel/trace v1.39.0 go.opentelemetry.io/otel/trace v1.38.0
golang.org/x/crypto v0.46.0 golang.org/x/crypto v0.46.0
golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac
golang.org/x/image v0.33.0 golang.org/x/image v0.33.0
@@ -384,7 +384,7 @@ require (
go.opencensus.io v0.24.0 // indirect go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect
go.opentelemetry.io/otel/metric v1.39.0 // indirect go.opentelemetry.io/otel/metric v1.38.0 // indirect
go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.opentelemetry.io/proto/otlp v1.7.1 // indirect
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect go.uber.org/zap v1.27.0 // indirect

24
go.sum
View File

@@ -973,8 +973,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
github.com/opensearch-project/opensearch-go/v4 v4.6.0 h1:Ac8aLtDSmLEyOmv0r1qhQLw3b4vcUhE42NE9k+Z4cRc= github.com/opensearch-project/opensearch-go/v4 v4.5.0 h1:26XckmmF6MhlXt91Bu1yY6R51jy1Ns/C3XgIfvyeTRo=
github.com/opensearch-project/opensearch-go/v4 v4.6.0/go.mod h1:3iZtb4SNt3IzaxavKq0dURh1AmtVgYW71E4XqmYnIiQ= github.com/opensearch-project/opensearch-go/v4 v4.5.0/go.mod h1:VmFc7dqOEM3ZtLhrpleOzeq+cqUgNabqQG5gX0xId64=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= 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 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
@@ -1315,8 +1315,8 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg=
go.opentelemetry.io/contrib/zpages v0.63.0 h1:TppOKuZGbqXMgsfjqq3i09N5Vbo1JLtLImUqiTPGnX4= go.opentelemetry.io/contrib/zpages v0.63.0 h1:TppOKuZGbqXMgsfjqq3i09N5Vbo1JLtLImUqiTPGnX4=
go.opentelemetry.io/contrib/zpages v0.63.0/go.mod h1:5F8uugz75ay/MMhRRhxAXY33FuaI8dl7jTxefrIy5qk= go.opentelemetry.io/contrib/zpages v0.63.0/go.mod h1:5F8uugz75ay/MMhRRhxAXY33FuaI8dl7jTxefrIy5qk=
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54=
@@ -1325,14 +1325,14 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 h1:kJxSDN4SgWWTjG/hPp3O7LCGLcHXFlvS2/FFOrwL+SE= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 h1:kJxSDN4SgWWTjG/hPp3O7LCGLcHXFlvS2/FFOrwL+SE=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0/go.mod h1:mgIOzS7iZeKJdeB8/NYHrJ48fdGc71Llo5bJ1J4DWUE= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0/go.mod h1:mgIOzS7iZeKJdeB8/NYHrJ48fdGc71Llo5bJ1J4DWUE=
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4=
go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=

View File

@@ -61,7 +61,7 @@ var serviceCommands = []register.Command{
}, },
func(cfg *config.Config) *cobra.Command { func(cfg *config.Config) *cobra.Command {
return ServiceCommand(cfg, cfg.Antivirus.Service.Name, antivirus.GetCommands(cfg.Antivirus), func(c *config.Config) { return ServiceCommand(cfg, cfg.Antivirus.Service.Name, antivirus.GetCommands(cfg.Antivirus), func(c *config.Config) {
cfg.Antivirus.Commons = cfg.Commons // cfg.Antivirus.Commons = cfg.Commons // antivirus needs no commons atm
}) })
}, },
func(cfg *config.Config) *cobra.Command { func(cfg *config.Config) *cobra.Command {

View File

@@ -34,7 +34,7 @@ var (
// LatestTag is the latest released version plus the dev meta version. // LatestTag is the latest released version plus the dev meta version.
// Will be overwritten by the release pipeline // Will be overwritten by the release pipeline
// Needs a manual change for every tagged release // Needs a manual change for every tagged release
LatestTag = "4.1.0+dev" LatestTag = "4.0.0-rc.3+dev"
// Date indicates the build date. // Date indicates the build date.
// This has been removed, it looks like you can only replace static strings with recent go versions // This has been removed, it looks like you can only replace static strings with recent go versions

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/activitylog/pkg/command"
"github.com/opencloud-eu/opencloud/services/activitylog/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-05 00:06+0000\n" "POT-Creation-Date: 2025-12-16 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n" "Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n"
"Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n" "Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n"

View File

@@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-02 00:06+0000\n" "POT-Creation-Date: 2025-12-13 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Mário Machado, 2025\n" "Last-Translator: Mário Machado, 2025\n"
"Language-Team: Portuguese (https://app.transifex.com/opencloud-eu/teams/204053/pt/)\n" "Language-Team: Portuguese (https://app.transifex.com/opencloud-eu/teams/204053/pt/)\n"

View File

@@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-06 00:06+0000\n" "POT-Creation-Date: 2025-12-17 00:03+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Quan Tran, 2025\n" "Last-Translator: Quan Tran, 2025\n"
"Language-Team: Vietnamese (https://app.transifex.com/opencloud-eu/teams/204053/vi/)\n" "Language-Team: Vietnamese (https://app.transifex.com/opencloud-eu/teams/204053/vi/)\n"

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/antivirus/pkg/command"
"github.com/opencloud-eu/opencloud/services/antivirus/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/app-provider/pkg/command"
"github.com/opencloud-eu/opencloud/services/app-provider/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/app-registry/pkg/command"
"github.com/opencloud-eu/opencloud/services/app-registry/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/audit/pkg/command"
"github.com/opencloud-eu/opencloud/services/audit/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/auth-app/pkg/command"
"github.com/opencloud-eu/opencloud/services/auth-app/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/auth-basic/pkg/command"
"github.com/opencloud-eu/opencloud/services/auth-basic/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/auth-bearer/pkg/command"
"github.com/opencloud-eu/opencloud/services/auth-bearer/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/auth-machine/pkg/command"
"github.com/opencloud-eu/opencloud/services/auth-machine/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/auth-service/pkg/command"
"github.com/opencloud-eu/opencloud/services/auth-service/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/clientlog/pkg/command"
"github.com/opencloud-eu/opencloud/services/clientlog/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/activitylog/pkg/command"
"github.com/opencloud-eu/opencloud/services/activitylog/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/eventhistory/pkg/command"
"github.com/opencloud-eu/opencloud/services/eventhistory/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/frontend/pkg/command"
"github.com/opencloud-eu/opencloud/services/frontend/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/gateway/pkg/command"
"github.com/opencloud-eu/opencloud/services/gateway/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/graph/pkg/command"
"github.com/opencloud-eu/opencloud/services/graph/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-05 00:06+0000\n" "POT-Creation-Date: 2025-12-16 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n" "Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n"
"Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n" "Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n"

View File

@@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-02 00:06+0000\n" "POT-Creation-Date: 2025-12-13 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Stephan Paternotte <stephan@paternottes.net>, 2025\n" "Last-Translator: Stephan Paternotte <stephan@paternottes.net>, 2025\n"
"Language-Team: Dutch (https://app.transifex.com/opencloud-eu/teams/204053/nl/)\n" "Language-Team: Dutch (https://app.transifex.com/opencloud-eu/teams/204053/nl/)\n"

View File

@@ -14,7 +14,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-02 00:06+0000\n" "POT-Creation-Date: 2025-12-13 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Radoslaw Posim, 2025\n" "Last-Translator: Radoslaw Posim, 2025\n"
"Language-Team: Polish (https://app.transifex.com/opencloud-eu/teams/204053/pl/)\n" "Language-Team: Polish (https://app.transifex.com/opencloud-eu/teams/204053/pl/)\n"

View File

@@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-02 00:06+0000\n" "POT-Creation-Date: 2025-12-13 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Mário Machado, 2025\n" "Last-Translator: Mário Machado, 2025\n"
"Language-Team: Portuguese (https://app.transifex.com/opencloud-eu/teams/204053/pt/)\n" "Language-Team: Portuguese (https://app.transifex.com/opencloud-eu/teams/204053/pt/)\n"

View File

@@ -12,7 +12,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-02 00:06+0000\n" "POT-Creation-Date: 2025-12-13 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Lulufox, 2025\n" "Last-Translator: Lulufox, 2025\n"
"Language-Team: Russian (https://app.transifex.com/opencloud-eu/teams/204053/ru/)\n" "Language-Team: Russian (https://app.transifex.com/opencloud-eu/teams/204053/ru/)\n"

View File

@@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-05 00:06+0000\n" "POT-Creation-Date: 2025-12-16 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: LinkinWires <darkinsonic13@gmail.com>, 2025\n" "Last-Translator: LinkinWires <darkinsonic13@gmail.com>, 2025\n"
"Language-Team: Ukrainian (https://app.transifex.com/opencloud-eu/teams/204053/uk/)\n" "Language-Team: Ukrainian (https://app.transifex.com/opencloud-eu/teams/204053/uk/)\n"

View File

@@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-06 00:06+0000\n" "POT-Creation-Date: 2025-12-17 00:03+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Quan Tran, 2025\n" "Last-Translator: Quan Tran, 2025\n"
"Language-Team: Vietnamese (https://app.transifex.com/opencloud-eu/teams/204053/vi/)\n" "Language-Team: Vietnamese (https://app.transifex.com/opencloud-eu/teams/204053/vi/)\n"

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/groups/pkg/command"
"github.com/opencloud-eu/opencloud/services/groups/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/idm/pkg/command"
"github.com/opencloud-eu/opencloud/services/idm/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/idp/pkg/command"
"github.com/opencloud-eu/opencloud/services/idp/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/invitations/pkg/command"
"github.com/opencloud-eu/opencloud/services/invitations/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/nats/pkg/command"
"github.com/opencloud-eu/opencloud/services/nats/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/notifications/pkg/command"
"github.com/opencloud-eu/opencloud/services/notifications/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -12,7 +12,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-02 00:06+0000\n" "POT-Creation-Date: 2025-12-13 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: miguel tapias, 2025\n" "Last-Translator: miguel tapias, 2025\n"
"Language-Team: Spanish (https://app.transifex.com/opencloud-eu/teams/204053/es/)\n" "Language-Team: Spanish (https://app.transifex.com/opencloud-eu/teams/204053/es/)\n"

View File

@@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-03 00:06+0000\n" "POT-Creation-Date: 2025-12-14 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n" "Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n"
"Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n" "Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n"

View File

@@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-02 00:06+0000\n" "POT-Creation-Date: 2025-12-13 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Stephan Paternotte <stephan@paternottes.net>, 2025\n" "Last-Translator: Stephan Paternotte <stephan@paternottes.net>, 2025\n"
"Language-Team: Dutch (https://app.transifex.com/opencloud-eu/teams/204053/nl/)\n" "Language-Team: Dutch (https://app.transifex.com/opencloud-eu/teams/204053/nl/)\n"

View File

@@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-02 00:06+0000\n" "POT-Creation-Date: 2025-12-13 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Mário Machado, 2025\n" "Last-Translator: Mário Machado, 2025\n"
"Language-Team: Portuguese (https://app.transifex.com/opencloud-eu/teams/204053/pt/)\n" "Language-Team: Portuguese (https://app.transifex.com/opencloud-eu/teams/204053/pt/)\n"

View File

@@ -12,7 +12,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-02 00:06+0000\n" "POT-Creation-Date: 2025-12-13 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Lulufox, 2025\n" "Last-Translator: Lulufox, 2025\n"
"Language-Team: Russian (https://app.transifex.com/opencloud-eu/teams/204053/ru/)\n" "Language-Team: Russian (https://app.transifex.com/opencloud-eu/teams/204053/ru/)\n"

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/ocdav/pkg/command"
"github.com/opencloud-eu/opencloud/services/ocdav/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/ocm/pkg/command"
"github.com/opencloud-eu/opencloud/services/ocm/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/ocs/pkg/command"
"github.com/opencloud-eu/opencloud/services/ocs/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/policies/pkg/command"
"github.com/opencloud-eu/opencloud/services/policies/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/postprocessing/pkg/command"
"github.com/opencloud-eu/opencloud/services/postprocessing/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/proxy/pkg/command"
"github.com/opencloud-eu/opencloud/services/proxy/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/search/pkg/command"
"github.com/opencloud-eu/opencloud/services/search/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/settings/pkg/command"
"github.com/opencloud-eu/opencloud/services/settings/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-03 00:06+0000\n" "POT-Creation-Date: 2025-12-14 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n" "Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n"
"Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n" "Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n"

View File

@@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-02 00:06+0000\n" "POT-Creation-Date: 2025-12-13 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: idoet <idoet@protonmail.ch>, 2025\n" "Last-Translator: idoet <idoet@protonmail.ch>, 2025\n"
"Language-Team: Indonesian (https://app.transifex.com/opencloud-eu/teams/204053/id/)\n" "Language-Team: Indonesian (https://app.transifex.com/opencloud-eu/teams/204053/id/)\n"

View File

@@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2025-12-25 00:05+0000\n" "POT-Creation-Date: 2025-12-18 00:04+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: ii kaka, 2025\n" "Last-Translator: ii kaka, 2025\n"
"Language-Team: Japanese (https://app.transifex.com/opencloud-eu/teams/204053/ja/)\n" "Language-Team: Japanese (https://app.transifex.com/opencloud-eu/teams/204053/ja/)\n"
@@ -44,7 +44,7 @@ msgstr "ファイルの拒否"
#. translation for the 'instant' email interval option #. translation for the 'instant' email interval option
#: pkg/store/defaults/templates.go:48 #: pkg/store/defaults/templates.go:48
msgid "Instant" msgid "Instant"
msgstr "即時" msgstr "即時 "
#. translation for the 'never' email interval option #. translation for the 'never' email interval option
#: pkg/store/defaults/templates.go:54 #: pkg/store/defaults/templates.go:54
@@ -111,7 +111,7 @@ msgstr "選択された値:"
#. name of the notification option 'Share Expired' #. name of the notification option 'Share Expired'
#: pkg/store/defaults/templates.go:16 #: pkg/store/defaults/templates.go:16
msgid "Share Expired" msgid "Share Expired"
msgstr "共有期限切れ" msgstr " 共有期限切れ"
#. name of the notification option 'Share Received' #. name of the notification option 'Share Received'
#: pkg/store/defaults/templates.go:8 #: pkg/store/defaults/templates.go:8

View File

@@ -13,7 +13,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-02 00:06+0000\n" "POT-Creation-Date: 2025-12-13 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Radoslaw Posim, 2025\n" "Last-Translator: Radoslaw Posim, 2025\n"
"Language-Team: Polish (https://app.transifex.com/opencloud-eu/teams/204053/pl/)\n" "Language-Team: Polish (https://app.transifex.com/opencloud-eu/teams/204053/pl/)\n"

View File

@@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-02 00:06+0000\n" "POT-Creation-Date: 2025-12-13 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Mário Machado, 2025\n" "Last-Translator: Mário Machado, 2025\n"
"Language-Team: Portuguese (https://app.transifex.com/opencloud-eu/teams/204053/pt/)\n" "Language-Team: Portuguese (https://app.transifex.com/opencloud-eu/teams/204053/pt/)\n"

View File

@@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-05 00:06+0000\n" "POT-Creation-Date: 2025-12-16 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: LinkinWires <darkinsonic13@gmail.com>, 2025\n" "Last-Translator: LinkinWires <darkinsonic13@gmail.com>, 2025\n"
"Language-Team: Ukrainian (https://app.transifex.com/opencloud-eu/teams/204053/uk/)\n" "Language-Team: Ukrainian (https://app.transifex.com/opencloud-eu/teams/204053/uk/)\n"

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/sharing/pkg/command"
"github.com/opencloud-eu/opencloud/services/sharing/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/sse/pkg/command"
"github.com/opencloud-eu/opencloud/services/sse/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/storage-publiclink/pkg/command"
"github.com/opencloud-eu/opencloud/services/storage-publiclink/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/storage-shares/pkg/command"
"github.com/opencloud-eu/opencloud/services/storage-shares/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/storage-system/pkg/command"
"github.com/opencloud-eu/opencloud/services/storage-system/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/storage-users/pkg/command"
"github.com/opencloud-eu/opencloud/services/storage-users/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/thumbnails/pkg/command"
"github.com/opencloud-eu/opencloud/services/thumbnails/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -20,7 +20,6 @@ import (
"golang.org/x/image/math/fixed" "golang.org/x/image/math/fixed"
"github.com/dhowden/tag" "github.com/dhowden/tag"
thumbnailerErrors "github.com/opencloud-eu/opencloud/services/thumbnails/pkg/errors" thumbnailerErrors "github.com/opencloud-eu/opencloud/services/thumbnails/pkg/errors"
) )
@@ -143,11 +142,7 @@ Scan: // Label for the scanner loop, so we can break it easily
textResult.MergeCommon(DefaultMergeMap) textResult.MergeCommon(DefaultMergeMap)
for _, sRange := range textResult.ScriptRanges { for _, sRange := range textResult.ScriptRanges {
targetFontFace, err := t.fontLoader.LoadFaceForScript(sRange.TargetScript) targetFontFace, _ := t.fontLoader.LoadFaceForScript(sRange.TargetScript)
if err != nil {
return nil, err
}
// if the target script is "_unknown" it's expected that the loaded face // if the target script is "_unknown" it's expected that the loaded face
// uses the default font // uses the default font
faceHeight := targetFontFace.Face.Metrics().Height faceHeight := targetFontFace.Face.Metrics().Height
@@ -161,18 +156,15 @@ Scan: // Label for the scanner loop, so we can break it easily
if canvas.Dot.Y > maxY { if canvas.Dot.Y > maxY {
break Scan break Scan
} }
drawWord(canvas, textResult.Text[initialByte:sRangeSpace], minX, maxX, height, maxY, true)
drawWord(canvas, textResult.Text[initialByte:sRangeSpace], minX, maxX, height, maxY)
initialByte = sRangeSpace initialByte = sRangeSpace
} }
if initialByte <= sRange.High { if initialByte <= sRange.High {
// some bytes left to be written // some bytes left to be written
if canvas.Dot.Y > maxY { if canvas.Dot.Y > maxY {
break Scan break Scan
} }
drawWord(canvas, textResult.Text[initialByte:sRange.High+1], minX, maxX, height, maxY, len(sRange.Spaces) > 0)
drawWord(canvas, textResult.Text[initialByte:sRange.High+1], minX, maxX, height, maxY)
} }
} }
@@ -243,58 +235,43 @@ func extractBase64ImageFromGGP(ggp *GGPStruct) (string, error) {
// need to draw the word in a new line // need to draw the word in a new line
// //
// Note that the word will likely start with a white space char // Note that the word will likely start with a white space char
func drawWord(canvas *font.Drawer, word string, minX, maxX, incY, maxY fixed.Int26_6) { func drawWord(canvas *font.Drawer, word string, minX, maxX, incY, maxY fixed.Int26_6, goToNewLine bool) {
// calculate the actual measurement of the string at a given X position bbox, _ := canvas.BoundString(word)
measure := func(s string, dotX fixed.Int26_6) (min, max fixed.Int26_6) { if bbox.Max.X <= maxX {
bbox, _ := canvas.BoundString(s) // word fits in the current line
return dotX + bbox.Min.X, dotX + bbox.Max.X
}
// first try to draw the whole word
absMin, absMax := measure(word, canvas.Dot.X)
if absMin >= minX && absMax <= maxX {
canvas.DrawString(word) canvas.DrawString(word)
return } else {
} // word doesn't fit -> retry in a new line
trimmedWord := strings.TrimSpace(word)
oldDot := canvas.Dot
// try to draw the trimmed word in a new line canvas.Dot.X = minX
trimmed := strings.TrimSpace(word) canvas.Dot.Y += incY
oldDot := canvas.Dot bbox2, _ := canvas.BoundString(trimmedWord)
canvas.Dot.X = minX if goToNewLine && bbox2.Max.X <= maxX {
canvas.Dot.Y += incY if canvas.Dot.Y > maxY {
// Don't draw if we're over the Y limit
if canvas.Dot.Y <= maxY { return
tMin, tMax := measure(trimmed, canvas.Dot.X) }
if tMin >= minX && tMax <= maxX { canvas.DrawString(trimmedWord)
canvas.DrawString(trimmed) } else {
return // word doesn't fit in a new line -> draw as many chars as possible
canvas.Dot = oldDot
for _, char := range trimmedWord {
charBytes := []byte(string(char))
bbox3, _ := canvas.BoundBytes(charBytes)
if bbox3.Max.X > maxX {
canvas.Dot.X = minX
canvas.Dot.Y += incY
if canvas.Dot.Y > maxY {
// Don't draw if we're over the Y limit
return
}
}
canvas.DrawBytes(charBytes)
}
} }
} }
// if the trimmed word is still too big, draw it char by char
canvas.Dot = oldDot
for _, char := range trimmed {
s := string(char)
_, cMax := measure(s, canvas.Dot.X)
if cMax > maxX {
canvas.Dot.X = minX
canvas.Dot.Y += incY
}
// stop drawing if we exceed maxY
if canvas.Dot.Y > maxY {
return
}
// ensure that we don't start drawing before minX
cMin, _ := measure(s, canvas.Dot.X)
if cMin < minX {
canvas.Dot.X += minX - cMin
}
canvas.DrawString(s)
}
} }
// ForType returns the converter for the specified mimeType // ForType returns the converter for the specified mimeType

View File

@@ -149,17 +149,6 @@ var _ = Describe("ImageDecoder", func() {
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(img).ToNot(BeNil()) Expect(img).ToNot(BeNil())
}) })
It("fails if the font is missing", func() {
decoder.fontLoader.fontMapData = &FontMapData{
FMap: &FontMap{
DefaultFont: "/some/unknown/font.otf",
},
}
img, err := decoder.Convert(bytes.NewReader([]byte("This is a test text")))
Expect(err).To(HaveOccurred())
Expect(img).To(BeNil())
})
}) })
Describe("test ForType", func() { Describe("test ForType", func() {

View File

@@ -12,14 +12,13 @@ import (
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/golang-jwt/jwt/v5" "github.com/golang-jwt/jwt/v5"
"github.com/pkg/errors"
merrors "go-micro.dev/v4/errors"
"google.golang.org/grpc/metadata"
revactx "github.com/opencloud-eu/reva/v2/pkg/ctx" revactx "github.com/opencloud-eu/reva/v2/pkg/ctx"
"github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool" "github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool"
"github.com/opencloud-eu/reva/v2/pkg/storagespace" "github.com/opencloud-eu/reva/v2/pkg/storagespace"
"github.com/opencloud-eu/reva/v2/pkg/utils" "github.com/opencloud-eu/reva/v2/pkg/utils"
"github.com/pkg/errors"
merrors "go-micro.dev/v4/errors"
"google.golang.org/grpc/metadata"
"github.com/opencloud-eu/opencloud/pkg/log" "github.com/opencloud-eu/opencloud/pkg/log"
thumbnailssvc "github.com/opencloud-eu/opencloud/protogen/gen/opencloud/services/thumbnails/v0" thumbnailssvc "github.com/opencloud-eu/opencloud/protogen/gen/opencloud/services/thumbnails/v0"
@@ -170,10 +169,6 @@ func (g Thumbnail) handleCS3Source(ctx context.Context, req *thumbnailssvc.GetTh
} }
pp := preprocessor.ForType(sRes.GetInfo().GetMimeType(), ppOpts) pp := preprocessor.ForType(sRes.GetInfo().GetMimeType(), ppOpts)
img, err := pp.Convert(r) img, err := pp.Convert(r)
if err != nil {
g.logger.Error().Err(err).Msg("failed to convert image")
}
if img == nil || err != nil { if img == nil || err != nil {
return "", merrors.NotFound(g.serviceID, "could not get image") return "", merrors.NotFound(g.serviceID, "could not get image")
} }

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/userlog/pkg/command"
"github.com/opencloud-eu/opencloud/services/userlog/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-05 00:06+0000\n" "POT-Creation-Date: 2025-12-16 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n" "Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n"
"Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n" "Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n"

View File

@@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2025-12-25 00:05+0000\n" "POT-Creation-Date: 2025-12-19 00:05+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: ii kaka, 2025\n" "Last-Translator: ii kaka, 2025\n"
"Language-Team: Japanese (https://app.transifex.com/opencloud-eu/teams/204053/ja/)\n" "Language-Team: Japanese (https://app.transifex.com/opencloud-eu/teams/204053/ja/)\n"
@@ -52,7 +52,7 @@ msgstr "メンバーシップの期限が切れました"
#: pkg/service/templates.go:13 #: pkg/service/templates.go:13
msgid "Policies enforced" msgid "Policies enforced"
msgstr "ポリシーが適用されました" msgstr " ポリシーが適用されました"
#: pkg/service/templates.go:23 #: pkg/service/templates.go:23
msgid "Removed from Space" msgid "Removed from Space"
@@ -84,7 +84,7 @@ msgstr "スペースが共有されました"
#: pkg/service/templates.go:8 #: pkg/service/templates.go:8
msgid "Virus found" msgid "Virus found"
msgstr "ウイルスが検出されました" msgstr " ウイルスが検出されました"
#: pkg/service/templates.go:9 #: pkg/service/templates.go:9
msgid "Virus found in {resource}. Upload not possible. Virus: {virus}" msgid "Virus found in {resource}. Upload not possible. Virus: {virus}"

View File

@@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-02 00:06+0000\n" "POT-Creation-Date: 2025-12-13 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Stephan Paternotte <stephan@paternottes.net>, 2025\n" "Last-Translator: Stephan Paternotte <stephan@paternottes.net>, 2025\n"
"Language-Team: Dutch (https://app.transifex.com/opencloud-eu/teams/204053/nl/)\n" "Language-Team: Dutch (https://app.transifex.com/opencloud-eu/teams/204053/nl/)\n"

View File

@@ -13,7 +13,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-02 00:06+0000\n" "POT-Creation-Date: 2025-12-13 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Radoslaw Posim, 2025\n" "Last-Translator: Radoslaw Posim, 2025\n"
"Language-Team: Polish (https://app.transifex.com/opencloud-eu/teams/204053/pl/)\n" "Language-Team: Polish (https://app.transifex.com/opencloud-eu/teams/204053/pl/)\n"

View File

@@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n" "Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-01-02 00:06+0000\n" "POT-Creation-Date: 2025-12-13 00:02+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n" "PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Mário Machado, 2025\n" "Last-Translator: Mário Machado, 2025\n"
"Language-Team: Portuguese (https://app.transifex.com/opencloud-eu/teams/204053/pt/)\n" "Language-Team: Portuguese (https://app.transifex.com/opencloud-eu/teams/204053/pt/)\n"

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/users/pkg/command"
"github.com/opencloud-eu/opencloud/services/users/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/web/pkg/command"
"github.com/opencloud-eu/opencloud/services/web/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/webdav/pkg/command"
"github.com/opencloud-eu/opencloud/services/webdav/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/opencloud-eu/opencloud/services/webfinger/pkg/command"
"github.com/opencloud-eu/opencloud/services/webfinger/pkg/config/defaults"
)
func main() {
cfg := defaults.DefaultConfig()
cfg.Context, _ = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
if err := command.Execute(cfg); err != nil {
os.Exit(1)
}
}

View File

@@ -198,7 +198,7 @@ class HttpRequestHelper {
// wait for post-processing to finish if applicable // wait for post-processing to finish if applicable
if (WebdavHelper::isDAVRequest($url) if (WebdavHelper::isDAVRequest($url)
&& \str_starts_with($url, OcHelper::getServerUrl()) && \str_starts_with($url, OcHelper::getServerUrl())
&& \in_array($method, ["PUT", "MOVE", "COPY", "MKCOL"]) && \in_array($method, ["PUT", "MOVE", "COPY"])
&& \in_array($response->getStatusCode(), [Response::HTTP_CREATED, Response::HTTP_NO_CONTENT]) && \in_array($response->getStatusCode(), [Response::HTTP_CREATED, Response::HTTP_NO_CONTENT])
&& OcConfigHelper::getPostProcessingDelay() === 0 && OcConfigHelper::getPostProcessingDelay() === 0
) { ) {

View File

@@ -1577,7 +1577,7 @@ class FeatureContext extends BehatVariablesContext {
* *
* @return mixed * @return mixed
*/ */
public function getJsonDecodedResponseBodyContent(ResponseInterface $response = null): mixed { public function getJsonDecodedResponseBodyContent(?ResponseInterface $response = null): mixed {
$response = $response ?? $this->response; $response = $response ?? $this->response;
$response->getBody()->rewind(); $response->getBody()->rewind();
return HttpRequestHelper::getJsonDecodedResponseBodyContent($response); return HttpRequestHelper::getJsonDecodedResponseBodyContent($response);

View File

@@ -377,7 +377,7 @@ class NotificationContext implements Context {
} }
/** /**
* @Then /^user "([^"]*)" should get a notification with subject "([^"]*)" and message:$/ * @Then /^user "([^"]*)" should (?:get|have) a notification with subject "([^"]*)" and message:$/
* *
* @param string $user * @param string $user
* @param string $subject * @param string $subject
@@ -411,10 +411,10 @@ class NotificationContext implements Context {
throw new \Exception("Notification was not found even after retrying for 5 seconds."); throw new \Exception("Notification was not found even after retrying for 5 seconds.");
} }
$expectedMessage = $table->getColumnsHash()[0]['message']; $expectedMessage = $table->getColumnsHash()[0]['message'];
Assert::assertStringStartsWith( Assert::assertSame(
$expectedMessage, $expectedMessage,
$actualMessage, $actualMessage,
__METHOD__ . "expected message to start with '$expectedMessage' but found'$actualMessage'" __METHOD__ . "expected message to be '$expectedMessage' but found'$actualMessage'"
); );
} }
@@ -441,10 +441,10 @@ class NotificationContext implements Context {
if (\count($notification) === 1) { if (\count($notification) === 1) {
$actualMessage = str_replace(["\r", "\r"], " ", $notification[0]->message); $actualMessage = str_replace(["\r", "\r"], " ", $notification[0]->message);
$expectedMessage = $table->getColumnsHash()[0]['message']; $expectedMessage = $table->getColumnsHash()[0]['message'];
Assert::assertStringStartsWith( Assert::assertSame(
$expectedMessage, $expectedMessage,
$actualMessage, $actualMessage,
__METHOD__ . "expected message to start with '$expectedMessage' but found'$actualMessage'" __METHOD__ . "expected message to be '$expectedMessage' but found'$actualMessage'"
); );
$response = $this->userDeletesNotification($user); $response = $this->userDeletesNotification($user);
$this->featureContext->theHTTPStatusCodeShouldBe(200, '', $response); $this->featureContext->theHTTPStatusCodeShouldBe(200, '', $response);
@@ -462,7 +462,7 @@ class NotificationContext implements Context {
} }
/** /**
* @Then user :user should not get a notification related to resource :resource with subject :subject * @Then user :user should not have a notification related to resource :resource with subject :subject
* *
* @param string $user * @param string $user
* @param string $resource * @param string $resource

View File

@@ -1025,7 +1025,7 @@ trait Provisioning {
*/ */
public function userHasBeenCreated( public function userHasBeenCreated(
array $userData, array $userData,
string $byUser = null ?string $byUser = null
): void { ): void {
$userId = null; $userId = null;

View File

@@ -450,7 +450,7 @@ trait Sharing {
string $user, string $user,
string $path, string $path,
bool $publicUpload = false, bool $publicUpload = false,
string $sharePassword = null, ?string $sharePassword = null,
$permissions = null, $permissions = null,
?string $linkName = null, ?string $linkName = null,
?string $expireDate = null ?string $expireDate = null
@@ -1207,7 +1207,7 @@ trait Sharing {
*/ */
public function deleteLastShareUsingSharingApi( public function deleteLastShareUsingSharingApi(
string $user, string $user,
string $sharer = null, ?string $sharer = null,
bool $deleteLastPublicLink = false bool $deleteLastPublicLink = false
): ResponseInterface { ): ResponseInterface {
$user = $this->getActualUsername($user); $user = $this->getActualUsername($user);
@@ -2672,7 +2672,7 @@ trait Sharing {
* @return ResponseInterface * @return ResponseInterface
* @throws GuzzleException * @throws GuzzleException
*/ */
public function expireShare(string $shareId = null): ResponseInterface { public function expireShare(?string $shareId = null): ResponseInterface {
$adminUser = $this->getAdminUsername(); $adminUser = $this->getAdminUsername();
if ($shareId === null) { if ($shareId === null) {
$shareId = $this->getLastCreatedUserGroupShareId(); $shareId = $this->getLastCreatedUserGroupShareId();

View File

@@ -1644,7 +1644,7 @@ trait WebDav {
string $user, string $user,
string $source, string $source,
string $destination, string $destination,
string $spaceId = null, ?string $spaceId = null,
?bool $isGivenStep = false ?bool $isGivenStep = false
): ResponseInterface { ): ResponseInterface {
$user = $this->getActualUsername($user); $user = $this->getActualUsername($user);
@@ -4054,7 +4054,7 @@ trait WebDav {
* *
* @return string|null * @return string|null
*/ */
public function getFileIdForPath(string $user, string $path, string $spaceId = null): ?string { public function getFileIdForPath(string $user, string $path, ?string $spaceId = null): ?string {
$user = $this->getActualUsername($user); $user = $this->getActualUsername($user);
try { try {
return WebDavHelper::getFileIdForPath( return WebDavHelper::getFileIdForPath(

View File

@@ -1,6 +1,6 @@
services: services:
acceptance-tests: acceptance-tests:
image: owncloudci/php:8.2 image: scharfvi/php-alpine-ci:8.4
working_dir: /woodpecker/src/github.com/opencloud-eu/opencloud working_dir: /woodpecker/src/github.com/opencloud-eu/opencloud
command: /bin/bash /test/run-tests.sh command: /bin/bash /test/run-tests.sh
environment: environment:

View File

@@ -36,13 +36,13 @@ Feature: antivirus
| <message> | | <message> |
And as "Alice" file "<new-file-name>" should not exist And as "Alice" file "<new-file-name>" should not exist
Examples: Examples:
| dav-path-version | file-name | new-file-name | message | | dav-path-version | file-name | new-file-name | message |
| old | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: | | old | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| old | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: | | old | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| new | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: | | new | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| new | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: | | new | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| spaces | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: | | spaces | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| spaces | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: | | spaces | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
Scenario Outline: upload a file with virus and a file without virus Scenario Outline: upload a file with virus and a file without virus
@@ -64,13 +64,13 @@ Feature: antivirus
Cheers. Cheers.
""" """
Examples: Examples:
| dav-path-version | file-name | new-file-name | message | | dav-path-version | file-name | new-file-name | message |
| old | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: | | old | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| old | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: | | old | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| new | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: | | new | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| new | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: | | new | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| spaces | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: | | spaces | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| spaces | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: | | spaces | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
Scenario Outline: upload a file with virus in chunks Scenario Outline: upload a file with virus in chunks
@@ -83,8 +83,8 @@ Feature: antivirus
# antivirus service can scan files during post-processing. on demand scanning is currently not available # antivirus service can scan files during post-processing. on demand scanning is currently not available
Then the HTTP status code should be "201" Then the HTTP status code should be "201"
And user "Alice" should get a notification with subject "Virus found" and message: And user "Alice" should get a notification with subject "Virus found" and message:
| message | | message |
| Virus found in myChunkedFile.txt. Upload not possible. Virus: | | Virus found in myChunkedFile.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
And as "Alice" file "/myChunkedFile.txt" should not exist And as "Alice" file "/myChunkedFile.txt" should not exist
Examples: Examples:
| dav-path-version | | dav-path-version |
@@ -110,13 +110,13 @@ Feature: antivirus
| <message> | | <message> |
And as "Alice" file "/uploadFolder/<new-file-name>" should not exist And as "Alice" file "/uploadFolder/<new-file-name>" should not exist
Examples: Examples:
| dav-path-version | file-name | new-file-name | message | | dav-path-version | file-name | new-file-name | message |
| old | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: | | old | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| old | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: | | old | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| new | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: | | new | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| new | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: | | new | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| spaces | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: | | spaces | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| spaces | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: | | spaces | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
@issue-10331 @issue-10331
Scenario Outline: public uploads a file with the virus to a password-protected public share Scenario Outline: public uploads a file with the virus to a password-protected public share
@@ -136,13 +136,13 @@ Feature: antivirus
| <message> | | <message> |
And as "Alice" file "/uploadFolder/<new-file-name>" should not exist And as "Alice" file "/uploadFolder/<new-file-name>" should not exist
Examples: Examples:
| dav-path-version | file-name | new-file-name | message | | dav-path-version | file-name | new-file-name | message |
| old | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: | | old | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| old | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: | | old | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| new | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: | | new | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| new | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: | | new | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| spaces | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: | | spaces | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| spaces | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: | | spaces | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
Scenario Outline: upload a file with virus to a user share Scenario Outline: upload a file with virus to a user share
@@ -164,13 +164,13 @@ Feature: antivirus
And as "Brian" file "/Shares/uploadFolder/<new-file-name>" should not exist And as "Brian" file "/Shares/uploadFolder/<new-file-name>" should not exist
And as "Alice" file "/uploadFolder/<new-file-name>" should not exist And as "Alice" file "/uploadFolder/<new-file-name>" should not exist
Examples: Examples:
| dav-path-version | file-name | new-file-name | message | | dav-path-version | file-name | new-file-name | message |
| old | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: | | old | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| old | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: | | old | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| new | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: | | new | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| new | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: | | new | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| spaces | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: | | spaces | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| spaces | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: | | spaces | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
Scenario Outline: upload a file with virus to a group share Scenario Outline: upload a file with virus to a group share
@@ -195,13 +195,13 @@ Feature: antivirus
And as "Brian" file "/Shares/uploadFolder/<new-file-name>" should not exist And as "Brian" file "/Shares/uploadFolder/<new-file-name>" should not exist
And as "Alice" file "/uploadFolder/<new-file-name>" should not exist And as "Alice" file "/uploadFolder/<new-file-name>" should not exist
Examples: Examples:
| dav-path-version | file-name | new-file-name | message | | dav-path-version | file-name | new-file-name | message |
| old | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: | | old | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| old | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: | | old | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| new | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: | | new | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| new | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: | | new | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| spaces | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: | | spaces | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| spaces | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: | | spaces | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
Scenario Outline: upload a file with virus to a project space Scenario Outline: upload a file with virus to a project space
@@ -224,9 +224,9 @@ Feature: antivirus
And for user "Alice" the space "new-space" should not contain these entries: And for user "Alice" the space "new-space" should not contain these entries:
| /<new-file-name> | | /<new-file-name> |
Examples: Examples:
| file-name | new-file-name | message | | file-name | new-file-name | message |
| eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: | | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: | | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
Scenario Outline: upload a file with virus to a shared project space Scenario Outline: upload a file with virus to a shared project space
@@ -249,9 +249,9 @@ Feature: antivirus
And for user "Alice" the space "new-space" should not contain these entries: And for user "Alice" the space "new-space" should not contain these entries:
| /<new-file-name> | | /<new-file-name> |
Examples: Examples:
| file-name | new-file-name | message | | file-name | new-file-name | message |
| eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: | | eicar.com | virusFile1.txt | Virus found in virusFile1.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
| eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: | | eicar_com.zip | virusFile2.zip | Virus found in virusFile2.zip. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
@env-config @issue-6494 @env-config @issue-6494
Scenario Outline: upload a file with virus by setting antivirus infected file handling config to continue Scenario Outline: upload a file with virus by setting antivirus infected file handling config to continue
@@ -273,8 +273,8 @@ Feature: antivirus
When user "Alice" uploads file "filesForUpload/filesWithVirus/eicar.com" to "/aFileWithVirus.txt" using the WebDAV API When user "Alice" uploads file "filesForUpload/filesWithVirus/eicar.com" to "/aFileWithVirus.txt" using the WebDAV API
Then the HTTP status code should be "201" Then the HTTP status code should be "201"
And user "Alice" should get a notification with subject "Virus found" and message: And user "Alice" should get a notification with subject "Virus found" and message:
| message | | message |
| Virus found in aFileWithVirus.txt. Upload not possible. Virus: | | Virus found in aFileWithVirus.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
And as "Alice" file "/aFileWithVirus.txt" should not exist And as "Alice" file "/aFileWithVirus.txt" should not exist
Examples: Examples:
| dav-path-version | | dav-path-version |
@@ -307,12 +307,12 @@ Feature: antivirus
And as "Alice" file "/aFileWithVirus.txt" should not exist And as "Alice" file "/aFileWithVirus.txt" should not exist
Examples: Examples:
| dav-path-version | language | subject | message | | dav-path-version | language | subject | message |
| old | es | Virus encontrado | Virus encontrado en aFileWithVirus.txt. La subida no ha sido posible. Virus: | | old | es | Virus encontrado | Virus encontrado en aFileWithVirus.txt. La subida no ha sido posible. Virus: Win.Test.EICAR_HDB-1 |
| new | es | Virus encontrado | Virus encontrado en aFileWithVirus.txt. La subida no ha sido posible. Virus: | | new | es | Virus encontrado | Virus encontrado en aFileWithVirus.txt. La subida no ha sido posible. Virus: Win.Test.EICAR_HDB-1 |
| spaces | es | Virus encontrado | Virus encontrado en aFileWithVirus.txt. La subida no ha sido posible. Virus: | | spaces | es | Virus encontrado | Virus encontrado en aFileWithVirus.txt. La subida no ha sido posible. Virus: Win.Test.EICAR_HDB-1 |
| old | de | Virus gefunden | In aFileWithVirus.txt wurde potenziell schädlicher Code gefunden. Das Hochladen wurde abgebrochen. Grund: | | old | de | Virus gefunden | In aFileWithVirus.txt wurde potenziell schädlicher Code gefunden. Das Hochladen wurde abgebrochen. Grund: Win.Test.EICAR_HDB-1 |
| new | de | Virus gefunden | In aFileWithVirus.txt wurde potenziell schädlicher Code gefunden. Das Hochladen wurde abgebrochen. Grund: | | new | de | Virus gefunden | In aFileWithVirus.txt wurde potenziell schädlicher Code gefunden. Das Hochladen wurde abgebrochen. Grund: Win.Test.EICAR_HDB-1 |
| spaces | de | Virus gefunden | In aFileWithVirus.txt wurde potenziell schädlicher Code gefunden. Das Hochladen wurde abgebrochen. Grund: | | spaces | de | Virus gefunden | In aFileWithVirus.txt wurde potenziell schädlicher Code gefunden. Das Hochladen wurde abgebrochen. Grund: Win.Test.EICAR_HDB-1 |
@issue-enterprise-5709 @issue-enterprise-5709
Scenario Outline: try to create a version of file by uploading virus content Scenario Outline: try to create a version of file by uploading virus content
@@ -322,8 +322,8 @@ Feature: antivirus
When user "Alice" uploads file with content "X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*" to "test.txt" using the WebDAV API When user "Alice" uploads file with content "X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*" to "test.txt" using the WebDAV API
Then the HTTP status code should be "204" Then the HTTP status code should be "204"
And user "Alice" should get a notification with subject "Virus found" and message: And user "Alice" should get a notification with subject "Virus found" and message:
| message | | message |
| Virus found in test.txt. Upload not possible. Virus: | | Virus found in test.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
And as "Alice" file "/test.txt" should exist And as "Alice" file "/test.txt" should exist
And the version folder of file "/test.txt" for user "Alice" should contain "1" element And the version folder of file "/test.txt" for user "Alice" should contain "1" element
And the content of file "/test.txt" for user "Alice" should be "hello nepal" And the content of file "/test.txt" for user "Alice" should be "hello nepal"
@@ -349,8 +349,8 @@ Feature: antivirus
When the public overwrites file "test.txt" with content "X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*" using the public WebDAV API When the public overwrites file "test.txt" with content "X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*" using the public WebDAV API
Then the HTTP status code should be "204" Then the HTTP status code should be "204"
And user "Alice" should get a notification with subject "Virus found" and message: And user "Alice" should get a notification with subject "Virus found" and message:
| message | | message |
| Virus found in test.txt. Upload not possible. Virus: | | Virus found in test.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
And the content of file "/test.txt" for user "Alice" should be "hello" And the content of file "/test.txt" for user "Alice" should be "hello"
Examples: Examples:
| dav-path-version | | dav-path-version |
@@ -376,8 +376,8 @@ Feature: antivirus
When user "Brian" uploads file with content "X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*" to "Shares/test.txt" using the WebDAV API When user "Brian" uploads file with content "X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*" to "Shares/test.txt" using the WebDAV API
Then the HTTP status code should be "204" Then the HTTP status code should be "204"
And user "Brian" should get a notification with subject "Virus found" and message: And user "Brian" should get a notification with subject "Virus found" and message:
| message | | message |
| Virus found in test.txt. Upload not possible. Virus: | | Virus found in test.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
And the content of file "/test.txt" for user "Alice" should be "hello" And the content of file "/test.txt" for user "Alice" should be "hello"
And the content of file "Shares/test.txt" for user "Brian" should be "hello" And the content of file "Shares/test.txt" for user "Brian" should be "hello"
Examples: Examples:
@@ -410,15 +410,15 @@ Feature: antivirus
When user "Brian" uploads file with content "X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*" to "Shares/uploadFolder/test.txt" using the WebDAV API When user "Brian" uploads file with content "X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*" to "Shares/uploadFolder/test.txt" using the WebDAV API
Then the HTTP status code should be "204" Then the HTTP status code should be "204"
And user "Brian" should get a notification for resource "test.txt" with subject "Virus found" and message: And user "Brian" should get a notification for resource "test.txt" with subject "Virus found" and message:
| message | | message |
| Virus found in test.txt. Upload not possible. Virus: | | Virus found in test.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
And the content of file "Shares/uploadFolder/test.txt" for user "Brian" should be "this is a test file." And the content of file "Shares/uploadFolder/test.txt" for user "Brian" should be "this is a test file."
And the content of file "uploadFolder/test.txt" for user "Alice" should be "this is a test file." And the content of file "uploadFolder/test.txt" for user "Alice" should be "this is a test file."
When user "Brian" uploads file with content "X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*" to "Shares/test.txt" using the WebDAV API When user "Brian" uploads file with content "X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*" to "Shares/test.txt" using the WebDAV API
Then the HTTP status code should be "204" Then the HTTP status code should be "204"
And user "Brian" should get a notification for resource "test.txt" with subject "Virus found" and message: And user "Brian" should get a notification for resource "test.txt" with subject "Virus found" and message:
| message | | message |
| Virus found in test.txt. Upload not possible. Virus: | | Virus found in test.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
And the content of file "Shares/test.txt" for user "Brian" should be "this is a test file." And the content of file "Shares/test.txt" for user "Brian" should be "this is a test file."
And the content of file "/test.txt" for user "Alice" should be "this is a test file." And the content of file "/test.txt" for user "Alice" should be "this is a test file."
Examples: Examples:
@@ -437,8 +437,8 @@ Feature: antivirus
When user "Alice" uploads a file inside space "new-space" with content "X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*" to ".space/readme.md" using the WebDAV API When user "Alice" uploads a file inside space "new-space" with content "X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*" to ".space/readme.md" using the WebDAV API
Then the HTTP status code should be "204" Then the HTTP status code should be "204"
And user "Alice" should get a notification with subject "Virus found" and message: And user "Alice" should get a notification with subject "Virus found" and message:
| message | | message |
| Virus found in readme.md. Upload not possible. Virus: | | Virus found in readme.md. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
And for user "Alice" the content of the file ".space/readme.md" of the space "new-space" should be "Here you can add a description for this Space." And for user "Alice" the content of the file ".space/readme.md" of the space "new-space" should be "Here you can add a description for this Space."
@@ -458,8 +458,8 @@ Feature: antivirus
When user "Brian" uploads a file inside space "new-space" with content "X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*" to ".space/readme.md" using the WebDAV API When user "Brian" uploads a file inside space "new-space" with content "X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*" to ".space/readme.md" using the WebDAV API
Then the HTTP status code should be "204" Then the HTTP status code should be "204"
And user "Brian" should get a notification with subject "Virus found" and message: And user "Brian" should get a notification with subject "Virus found" and message:
| message | | message |
| Virus found in readme.md. Upload not possible. Virus: | | Virus found in readme.md. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
And for user "Brian" the content of the file ".space/readme.md" of the space "new-space" should be "Here you can add a description for this Space." And for user "Brian" the content of the file ".space/readme.md" of the space "new-space" should be "Here you can add a description for this Space."
And for user "Alice" the content of the file ".space/readme.md" of the space "new-space" should be "Here you can add a description for this Space." And for user "Alice" the content of the file ".space/readme.md" of the space "new-space" should be "Here you can add a description for this Space."
@@ -478,7 +478,7 @@ Feature: antivirus
When user "Brian" uploads a file "filesForUpload/filesWithVirus/eicar.com" to "text.txt" in space "new-space" using the WebDAV API When user "Brian" uploads a file "filesForUpload/filesWithVirus/eicar.com" to "text.txt" in space "new-space" using the WebDAV API
Then the HTTP status code should be "204" Then the HTTP status code should be "204"
And user "Brian" should get a notification with subject "Virus found" and message: And user "Brian" should get a notification with subject "Virus found" and message:
| message | | message |
| Virus found in text.txt. Upload not possible. Virus: | | Virus found in text.txt. Upload not possible. Virus: Win.Test.EICAR_HDB-1 |
And for user "Brian" the content of the file "/text.txt" of the space "new-space" should be "hello world" And for user "Brian" the content of the file "/text.txt" of the space "new-space" should be "hello world"
And for user "Alice" the content of the file "/text.txt" of the space "new-space" should be "hello world" And for user "Alice" the content of the file "/text.txt" of the space "new-space" should be "hello world"

View File

@@ -27,10 +27,10 @@ Feature: Delete notification
Scenario: delete a notification Scenario: delete a notification
When user "Brian" deletes a notification related to resource "my_data" with subject "Resource shared" When user "Brian" deletes a notification related to resource "my_data" with subject "Resource shared"
Then the HTTP status code should be "200" Then the HTTP status code should be "200"
And user "Brian" should get a notification with subject "Resource shared" and message: And user "Brian" should have a notification with subject "Resource shared" and message:
| message | | message |
| Alice Hansen shared textfile1.txt with you | | Alice Hansen shared textfile1.txt with you |
But user "Brian" should not get a notification related to resource "my_data" with subject "Resource shared" But user "Brian" should not have a notification related to resource "my_data" with subject "Resource shared"
Scenario: delete all notifications Scenario: delete all notifications

View File

@@ -202,7 +202,7 @@ Feature: capabilities
"properties": { "properties": {
"edition": { "edition": {
"type": "string", "type": "string",
"enum": ["%edition%"] "enum": ["dev"]
}, },
"product": { "product": {
"type": "string", "type": "string",
@@ -240,7 +240,7 @@ Feature: capabilities
}, },
"edition": { "edition": {
"type": "string", "type": "string",
"enum": ["%edition%"] "enum": ["dev"]
}, },
"product": { "product": {
"type": "string", "type": "string",

View File

@@ -58,7 +58,7 @@ Feature: default capabilities for normal user
"const": "%versionstring%" "const": "%versionstring%"
}, },
"edition": { "edition": {
"const": "%edition%" "const": "dev"
}, },
"productname": { "productname": {
"const": "%productname%" "const": "%productname%"

View File

@@ -1,7 +1,7 @@
{ {
"config": { "config": {
"platform": { "platform": {
"php": "8.2" "php": "8.4"
}, },
"allow-plugins": { "allow-plugins": {
"composer/package-versions-deprecated": true "composer/package-versions-deprecated": true
@@ -20,7 +20,7 @@
"guzzlehttp/guzzle": "^7.7", "guzzlehttp/guzzle": "^7.7",
"phpunit/phpunit": "^9.6", "phpunit/phpunit": "^9.6",
"laminas/laminas-ldap": "^2.15", "laminas/laminas-ldap": "^2.15",
"ankitpokhrel/tus-php": "^2.3", "ankitpokhrel/tus-php": "^2.4",
"swaggest/json-schema": "^0.12.42", "swaggest/json-schema": "^0.12.42",
"splitbrain/php-archive": "^1.3" "splitbrain/php-archive": "^1.3"
} }

View File

@@ -1,8 +1,59 @@
version: "2"
run: run:
timeout: 10m
modules-download-mode: readonly modules-download-mode: readonly
linters-settings:
errcheck:
check-blank: true
check-type-assertions: false
errorlint:
check-generated: false
default-signifies-exhaustive: false
exhaustive:
default-signifies-exhaustive: false
gci:
sections:
- standard
- default
- prefix(github.com/opensearch-project/opensearch-go)
goconst:
min-len: 3
min-occurrences: 3
godox:
keywords:
- BUG
- FIXME
- HACK
goimports:
local-prefixes: github.com/opensearch-project/opensearch-go
lll:
line-length: 140
nolintlint:
allow-leading-space: false
require-explanation: true
require-specific: true
unparam:
check-exported: true
misspell:
locale: US
ignore-words:
- expect
- cancelled
prealloc:
simple: true
range-loops: true
for-loops: false
revive:
rules:
- name: exported
severity: error
disabled: false
arguments:
- "checkPrivateReceivers"
- "sayRepetitiveInsteadOfStutters"
linters: linters:
default: none disable-all: true
enable: enable:
- asasalint - asasalint
- asciicheck - asciicheck
@@ -19,7 +70,10 @@ linters:
- errchkjson - errchkjson
- errname - errname
- errorlint - errorlint
- execinquery
- exhaustive - exhaustive
- exportloopref
- gci
- ginkgolinter - ginkgolinter
- gocheckcompilerdirectives - gocheckcompilerdirectives
- gochecknoglobals - gochecknoglobals
@@ -27,11 +81,15 @@ linters:
- goconst - goconst
- gocritic - gocritic
- godox - godox
- gofmt
- gofumpt
- goheader - goheader
- goimports
- gomoddirectives - gomoddirectives
- gomodguard - gomodguard
- goprintffuncname - goprintffuncname
- gosec - gosec
- gosimple
- govet - govet
- grouper - grouper
- importas - importas
@@ -59,10 +117,12 @@ linters:
- rowserrcheck - rowserrcheck
- sqlclosecheck - sqlclosecheck
- staticcheck - staticcheck
- stylecheck
- tagalign - tagalign
- testpackage - testpackage
- thelper - thelper
- tparallel - tparallel
- typecheck
- unconvert - unconvert
- unparam - unparam
- unused - unused
@@ -70,110 +130,46 @@ linters:
- wastedassign - wastedassign
- whitespace - whitespace
- zerologlint - zerologlint
settings:
errcheck: issues:
check-type-assertions: false include:
check-blank: true - EXC0012
exhaustive: - EXC0014
default-signifies-exhaustive: false exclude-rules:
goconst: - path: (_test\.go|internal/)
min-len: 3 linters:
min-occurrences: 3 - cyclop
godox: - dupl
keywords: - errcheck
- BUG - gochecknoglobals
- FIXME - gochecknoinits
- HACK - goconst
lll: - noctx
line-length: 140 - linters:
misspell: - gosec
locale: US text: "math/rand"
ignore-rules: path: _test\.go
- expect - linters:
- cancelled - gosec
nolintlint: text: "TLS InsecureSkipVerify set true"
require-explanation: true path: (_test\.go|internal/)
require-specific: true - linters:
prealloc: - gosec
simple: true text: "G108: Profiling endpoint is automatically exposed on /debug/pprof"
range-loops: true path: _test\.go
for-loops: false - linters:
revive: - goconst
rules: path: opensearchapi\/api_
- name: exported - linters:
arguments: - errcheck
- checkPrivateReceivers text: "Error return value of `debugLogger.Logf` is not checked"
- sayRepetitiveInsteadOfStutters - linters:
severity: error - errcheck
disabled: false - gochecknoglobals
unparam: path: opensearchtransport\/logger\.go
check-exported: true - linters:
exclusions: - nestif
generated: lax path: opensearchtransport/opensearchtransport.go
presets: - linters:
- common-false-positives - dupl
- legacy path: (-params\.go|api_indices|api_dangling\.go|api_point_in_time\.go|rethrottle\.go|api_cat-.*\.go|plugins/security/api_\w+.go|plugins/security/api_.*-patch.go)
- std-error-handling
rules:
- linters:
- cyclop
- dupl
- errcheck
- gochecknoglobals
- gochecknoinits
- goconst
- noctx
path: (_test\.go|internal/)
- linters:
- gosec
path: _test\.go
text: math/rand
- linters:
- gosec
path: (_test\.go|internal/)
text: TLS InsecureSkipVerify set true
- linters:
- gosec
path: _test\.go
text: 'G108: Profiling endpoint is automatically exposed on /debug/pprof'
- linters:
- goconst
path: -params\.go
- linters:
- errcheck
text: Error return value of `debugLogger.Logf` is not checked
- linters:
- errcheck
- gochecknoglobals
path: opensearchtransport\/logger\.go
- linters:
- nestif
path: opensearchtransport/opensearchtransport.go
- linters:
- dupl
path: (-params\.go|api_indices|api_dangling\.go|api_point_in_time\.go|rethrottle\.go|api_cat-.*\.go|plugins/security/api_\w+.go|plugins/security/api_.*-patch.go)
paths:
- third_party$
- builtin$
- examples$
formatters:
enable:
- gci
- gofmt
- gofumpt
- goimports
settings:
gci:
sections:
- standard
- default
- prefix(github.com/opensearch-project/opensearch-go)
goimports:
local-prefixes:
- github.com/opensearch-project/opensearch-go
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$

View File

@@ -2,41 +2,6 @@
Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
## [4.6.0]
### Dependencies
- Bump `github.com/aws/aws-sdk-go-v2/config` from 1.29.14 to 1.32.5 ([#707](https://github.com/opensearch-project/opensearch-go/pull/707), [#711](https://github.com/opensearch-project/opensearch-go/pull/711), [#719](https://github.com/opensearch-project/opensearch-go/pull/719), [#730](https://github.com/opensearch-project/opensearch-go/pull/730), [#737](https://github.com/opensearch-project/opensearch-go/pull/737), [#761](https://github.com/opensearch-project/opensearch-go/pull/761))
- Bump `github.com/aws/aws-sdk-go-v2` from 1.36.4 to 1.41.0 ([#710](https://github.com/opensearch-project/opensearch-go/pull/710), [#720](https://github.com/opensearch-project/opensearch-go/pull/720), [#759](https://github.com/opensearch-project/opensearch-go/pull/759))
- Bump `github.com/stretchr/testify` from 1.10.0 to 1.11.1 ([#728](https://github.com/opensearch-project/opensearch-go/pull/728))
- Bump `github.com/aws/aws-sdk-go` from 1.55.7 to 1.55.8 ([#716](https://github.com/opensearch-project/opensearch-go/pull/716))
### Added
- Adds new fields for Opensearch 3.0 ([#702](https://github.com/opensearch-project/opensearch-go/pull/702))
- Allow users to override signing port ([#721](https://github.com/opensearch-project/opensearch-go/pull/721))
- Add `phase_took` features supported from OpenSearch 2.12 ([#722](https://github.com/opensearch-project/opensearch-go/pull/722))
- Adds the action to refresh the search analyzers to the ISM plugin ([#686](https://github.com/opensearch-project/opensearch-go/pull/686))
### Changed
- Test against Opensearch 3.0 ([#702](https://github.com/opensearch-project/opensearch-go/pull/702))
- Add more SuggestOptions to SearchResp ([#713](https://github.com/opensearch-project/opensearch-go/pull/713))
- Updates Go version to 1.24 ([#674](https://github.com/opensearch-project/opensearch-go/pull/674))
- Replace `golang.org/x/exp/slices` usage with built-in `slices` ([#674](https://github.com/opensearch-project/opensearch-go/pull/674))
- Update golangci-linter to 1.64.8 ([#740](https://github.com/opensearch-project/opensearch-go/pull/740))
- Change MaxScore to pointer ([#740](https://github.com/opensearch-project/opensearch-go/pull/740))
- Update workflow action ([#760](https://github.com/opensearch-project/opensearch-go/pull/760))
- Migrate to golangci-lint v2 ([#760](https://github.com/opensearch-project/opensearch-go/pull/760))
### Deprecated
### Removed
### Fixed
- Missing "caused by" information in StructError ([#752](https://github.com/opensearch-project/opensearch-go/pull/752))
- Add missing `ignore_unavailable`, `allow_no_indices`, and `expand_wildcards` params to MSearch ([#757](https://github.com/opensearch-project/opensearch-go/pull/757))
- Fix `UpdateResp` to correctly parse the `get` field when `_source` is requested in update operations. ([#739](https://github.com/opensearch-project/opensearch-go/pull/739))
### Security
## [4.5.0] ## [4.5.0]
### Dependencies ### Dependencies
@@ -325,7 +290,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Uses `[]string` instead of `string` in `SnapshotDeleteRequest` ([#237](https://github.com/opensearch-project/opensearch-go/pull/237)) - Uses `[]string` instead of `string` in `SnapshotDeleteRequest` ([#237](https://github.com/opensearch-project/opensearch-go/pull/237))
- Updates workflows to reduce CI time, consolidate OpenSearch versions, update compatibility matrix ([#242](https://github.com/opensearch-project/opensearch-go/pull/242)) - Updates workflows to reduce CI time, consolidate OpenSearch versions, update compatibility matrix ([#242](https://github.com/opensearch-project/opensearch-go/pull/242))
- Moves @svencowart to emeritus maintainers ([#270](https://github.com/opensearch-project/opensearch-go/pull/270)) - Moves @svencowart to emeritus maintainers ([#270](https://github.com/opensearch-project/opensearch-go/pull/270))
- Reads, closes and replaces the http Response Body ([#300](https://github.com/opensearch-project/opensearch-go/pull/300)) - Reads, closes and replaces the http Reponse Body ([#300](https://github.com/opensearch-project/opensearch-go/pull/300))
### Fixed ### Fixed
@@ -364,7 +329,6 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Bumps `github.com/stretchr/testify` from 1.8.0 to 1.8.1 - Bumps `github.com/stretchr/testify` from 1.8.0 to 1.8.1
- Bumps `github.com/aws/aws-sdk-go` from 1.44.45 to 1.44.132 - Bumps `github.com/aws/aws-sdk-go` from 1.44.45 to 1.44.132
[4.6.0]: https://github.com/opensearch-project/opensearch-go/compare/v4.5.0...v4.6.0
[4.5.0]: https://github.com/opensearch-project/opensearch-go/compare/v4.4.0...v4.5.0 [4.5.0]: https://github.com/opensearch-project/opensearch-go/compare/v4.4.0...v4.5.0
[4.4.0]: https://github.com/opensearch-project/opensearch-go/compare/v4.3.0...v4.4.0 [4.4.0]: https://github.com/opensearch-project/opensearch-go/compare/v4.3.0...v4.4.0
[4.3.0]: https://github.com/opensearch-project/opensearch-go/compare/v4.2.0...v4.3.0 [4.3.0]: https://github.com/opensearch-project/opensearch-go/compare/v4.2.0...v4.3.0

View File

@@ -9,8 +9,6 @@ The below matrix shows the compatibility of the [`opensearch-go`](https://pkg.go
| -------------- | ------------------ | | -------------- | ------------------ |
| 1.x.0 | 1.x | | 1.x.0 | 1.x |
| 2.x.0 | 1.3.13-2.11.0 | | 2.x.0 | 1.3.13-2.11.0 |
| 3.x.0 | 1.3.13-2.12.0 |
| 4.x.0 | 1.3.20-3.0.0 |
## Upgrading ## Upgrading

View File

@@ -2,7 +2,7 @@
- [Getting Started](#getting-started) - [Getting Started](#getting-started)
- [Git Clone OpenSearch Go Client Repository](#git-clone-opensearch-go-client-repository) - [Git Clone OpenSearch Go Client Repository](#git-clone-opensearch-go-client-repository)
- [Install Prerequisites](#install-prerequisites) - [Install Prerequisites](#install-prerequisites)
- [Go 1.24](#go-124) - [Go 1.21](#go-121)
- [Docker](#docker) - [Docker](#docker)
- [Windows](#windows) - [Windows](#windows)
- [Unit Testing](#unit-testing) - [Unit Testing](#unit-testing)
@@ -29,9 +29,9 @@ Fork [opensearch-project/opensearch-go](https://github.com/opensearch-project/op
### Install Prerequisites ### Install Prerequisites
#### Go 1.24 #### Go 1.21
OpenSearch Go Client builds using [Go](https://go.dev/doc/install) 1.24 at a minimum. OpenSearch Go Client builds using [Go](https://go.dev/doc/install) 1.21 at a minimum.
#### Docker #### Docker

View File

@@ -6,6 +6,7 @@ This document contains a list of maintainers in this repo. See [opensearch-proje
| Maintainer | GitHub ID | Affiliation | | Maintainer | GitHub ID | Affiliation |
| ----------------------- | ----------------------------------------- | ------------------- | | ----------------------- | ----------------------------------------- | ------------------- |
| Daniel Doubrovkine | [dblock](https://github.com/dblock) | Independent |
| Jakob Hahn | [Jakob3xD](https://github.com/Jakob3xD) | Hetzner Online GmbH | | Jakob Hahn | [Jakob3xD](https://github.com/Jakob3xD) | Hetzner Online GmbH |
| Vacha Shah | [VachaShah](https://github.com/VachaShah) | Amazon | | Vacha Shah | [VachaShah](https://github.com/VachaShah) | Amazon |
| Vijayan Balasubramanian | [VijayanB](https://github.com/VijayanB) | Amazon | | Vijayan Balasubramanian | [VijayanB](https://github.com/VijayanB) | Amazon |
@@ -14,7 +15,6 @@ This document contains a list of maintainers in this repo. See [opensearch-proje
| Maintainer | GitHub ID | Affiliation | | Maintainer | GitHub ID | Affiliation |
| ---------------------- | ------------------------------------------- | ----------- | | ---------------------- | ------------------------------------------- | ----------- |
| Daniel Doubrovkine | [dblock](https://github.com/dblock) | Independent |
| Jack Mazanec | [jmazanec15](https://github.com/jmazanec15) | Amazon | | Jack Mazanec | [jmazanec15](https://github.com/jmazanec15) | Amazon |
| Rob Cowart | [robcowart](https://github.com/robcowart) | ElastiFlow | | Rob Cowart | [robcowart](https://github.com/robcowart) | ElastiFlow |
| Sven Cowart | [svencowart](https://github.com/svencowart) | | | Sven Cowart | [svencowart](https://github.com/svencowart) | |

View File

@@ -80,7 +80,9 @@ build-coverage:
##@ Development ##@ Development
lint: ## Run lint on the package lint: ## Run lint on the package
@make linters @printf "\033[2m→ Running lint...\033[0m\n"
go vet github.com/opensearch-project/opensearch-go/...
go list github.com/opensearch-project/opensearch-go/... | 'grep' -v internal | xargs golint -set_exit_status
package := "prettier" package := "prettier"
lint.markdown: lint.markdown:
@@ -227,7 +229,7 @@ cluster.clean: ## Remove unused Docker volumes and networks
docker system prune --volumes --force docker system prune --volumes --force
linters: linters:
docker run -t --rm -v $$(pwd):/app -v ~/.cache/golangci-lint/v2.7.2:/root/.cache -w /app golangci/golangci-lint:v2.7.2 golangci-lint run --timeout=5m -v docker run -t --rm -v $$(pwd):/app -v ~/.cache/golangci-lint/v1.54.2:/root/.cache -w /app golangci/golangci-lint:v1.54.2 golangci-lint run --timeout=5m
workflow: ## Run all github workflow commands here sequentially workflow: ## Run all github workflow commands here sequentially

View File

@@ -75,26 +75,10 @@ type Err struct {
RootCause []RootCause `json:"root_cause"` RootCause []RootCause `json:"root_cause"`
Type string `json:"type"` Type string `json:"type"`
Reason string `json:"reason"` Reason string `json:"reason"`
CausedBy *CausedBy `json:"caused_by,omitempty"`
Index string `json:"index,omitempty"` Index string `json:"index,omitempty"`
IndexUUID string `json:"index_uuid,omitempty"` IndexUUID string `json:"index_uuid,omitempty"`
} }
// CausedBy represents the optional caused_by of an API error response. Causes can be nested
type CausedBy struct {
Type string `json:"type"`
Reason string `json:"reason"`
CausedBy *CausedBy `json:"caused_by,omitempty"`
}
// String returns a string representation of CausedBy, handling nested structures
func (c *CausedBy) String() string {
if c.CausedBy == nil {
return fmt.Sprintf("{type: %s, reason: %s}", c.Type, c.Reason)
}
return fmt.Sprintf("{type: %s, reason: %s, caused_by: %s}", c.Type, c.Reason, c.CausedBy)
}
// RootCause represents the root_cause of an API error response // RootCause represents the root_cause of an API error response
type RootCause struct { type RootCause struct {
Type string `json:"type"` Type string `json:"type"`
@@ -105,13 +89,7 @@ type RootCause struct {
// Error returns a string // Error returns a string
func (e StructError) Error() string { func (e StructError) Error() string {
result := fmt.Sprintf("status: %d, type: %s, reason: %s, root_cause: %s", e.Status, e.Err.Type, e.Err.Reason, e.Err.RootCause) return fmt.Sprintf("status: %d, type: %s, reason: %s, root_cause: %s", e.Status, e.Err.Type, e.Err.Reason, e.Err.RootCause)
if e.Err.CausedBy != nil {
result += fmt.Sprintf(", caused_by: %s", e.Err.CausedBy)
}
return result
} }
// UnmarshalJSON is a custom unmarshal function for StructError returning custom errors in special cases // UnmarshalJSON is a custom unmarshal function for StructError returning custom errors in special cases

View File

@@ -27,4 +27,4 @@
package version package version
// Client returns the client version as a string. // Client returns the client version as a string.
const Client = "4.6.0" const Client = "4.5.0"

View File

@@ -52,7 +52,7 @@ type AliasesResp struct {
response *opensearch.Response response *opensearch.Response
} }
// Inspect returns the Inspect type containing the raw *opensearch.Response // Inspect returns the Inspect type containing the raw *opensearch.Reponse
func (r AliasesResp) Inspect() Inspect { func (r AliasesResp) Inspect() Inspect {
return Inspect{Response: r.response} return Inspect{Response: r.response}
} }

View File

@@ -103,7 +103,7 @@ type BulkRespItem struct {
} `json:"error,omitempty"` } `json:"error,omitempty"`
} }
// Inspect returns the Inspect type containing the raw *opensearch.Response // Inspect returns the Inspect type containing the raw *opensearch.Reponse
func (r BulkResp) Inspect() Inspect { func (r BulkResp) Inspect() Inspect {
return Inspect{Response: r.response} return Inspect{Response: r.response}
} }

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