Compare commits

...

97 commits

Author SHA1 Message Date
Simon L.
5752556e4f
Merge pull request #7437 from nextcloud/enh/noid/insert-version-to-nextcloud
Some checks are pending
Codespell / Check spelling (push) Waiting to run
Json Validator / Json Validator (push) Waiting to run
Lint php / php-lint (push) Waiting to run
Lint php / php-lint-summary (push) Blocked by required conditions
PHP Deprecation Detector / PHP Deprecation Detector (push) Waiting to run
Playwright Tests on push / test (push) Waiting to run
Static analysis / static-psalm-analysis (push) Waiting to run
Shellcheck / Check Shell (push) Waiting to run
insert the AIO version into Nextcloud's system config
2026-01-28 15:40:59 +01:00
Simon L.
9871a3eb9a insert the AIO version into Nextcloud's system config
Signed-off-by: Simon L. <szaimen@e.mail.de>
2026-01-28 15:17:15 +01:00
Simon L.
e9108e3660
Merge pull request #7392 from nextcloud/configmanager-property-hooks
Use property hooks to replace classic getter and setter methods.
2026-01-28 15:10:34 +01:00
Simon L.
27020e608d
fix get-configurable-aio-variables.sh script
Signed-off-by: Simon L. <szaimen@e.mail.de>

Signed-off-by: Simon L. <szaimen@e.mail.de>
2026-01-28 13:28:07 +01:00
Simon L.
d813314494
Merge pull request #7499 from nextcloud/aio-dependency-update
PHP dependency updates
2026-01-28 13:16:56 +01:00
szaimen
0ee76078ad php dependency updates
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-01-28 12:03:53 +00:00
Pablo Zmdl
5ba678c082 Non-functional addition to camelizing nextcloud_mount to nextcloudMount
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 12:08:07 +01:00
Pablo Zmdl
5b6e0f30a6 Fix assignment of INSTALL_LATEST_MAJOR from env replacement
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
d9d4e3680f Fix residue from change to use start/commitTransaction()
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
659b1ca383 Fix calling booleanize
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
ec66b359e0 Check arguments to camelize() for usefulness
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
078f3caf8a Move all properties to the top of the file
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
3cfe307a5c Make nextcloudKeepDisabledApps an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
5bdcfd67eb Make 'enableNvidiaGpu' an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
5fc4951ba0 Make 'nextcloudEnableDriDevice' an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
0cb79a387f Make 'disableBackupSection' an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
08438aff42 Make 'apacheAdditionalNetwork' an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
dc5dc0215c Make 'collaboraSeccompDisabled' an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
22a26268e0 Helper to booleanize environment-or-config-values
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
c3477a7eb2 Make 'nextcloudAdditionalPhpExtensions' an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
d50dc2db1d Make 'nextcloudAdditionalApks' an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
4ad8fcf258 Make 'trustedCacertsDir' an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
63245430ef Make 'dockerSocketPath' an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
bfa2b64674 Make 'fulltextsearchJavaOptions' an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
365e1e34e4 Make 'borgRetentionPolicy' an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
0ed83c5258 Move get-configurable-aio-variables.sh into php/ folder
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
8b8f60f76b Camelize property nextcloud_memory_limit => nextcloudMemoryLimit
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
bbf41cfdd3 Camelize property nextcloud_upload_limit => nextcloudUploadLimit
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
f5cf7903ad Camelize property nextcloud_datadir_mount => nextcloudDatadirMount
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
f35a0b4367 Camelize property nextcloud_mount => nextcloudMount
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
f7c5115c70 Camelize property talk_port => talkPort
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
567f072ee0 Camelize property apache_port => apachePort
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
00ce78d703 Camelize property turn_domain => turnDomain
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
c4aa148bff Camelize property aio_community_containers => aioCommunityContainers
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
b499001501 Camelize property collabora_additional_options => collaboraAdditionalOptions
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
5373471ed8 Camelize property collabora_dictionaries => collaboraDictionaries
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
efe8317446 Camelize property nextcloud_max_time => nextcloudMaxTime
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:57 +01:00
Pablo Zmdl
41c92b814f Camelize key names from aio_variables from container specs
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
f17db4fac1 Camelize property apache_ip_binding => apacheIpBinding
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
5cac2dcf12 Camelize property borg_restore_password => borgRestorePassword
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
284411c369 Camelize property borg_remote_repo => borgRemoteRepo
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
62856e78bb Camelize property borg_backup_host_location => borgBackupHostLocation
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
2425a07772 Camelize property install_latest_major => installLatestMajor
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
68f811b25f Camelize property AIO_URL => aioUrl
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
62a21dd34a Camelize property instance_restore_attempt => instanceRestoreAttempt
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
dd5d51cb2a Camelize property AIO_TOKEN => aioToken
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
27fd1e82ab Turn install_latest_major property into a string so we can save a version string or number
I chose a string instead of an integer so we have more freedom what to
actually save (maybe we want to include minor version digits at one point).

Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
3bb2ce6e4c Type-cast get values to fix handling old config data
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
dac5cfd917 Don't write the default value to disk
This matches the previous behaviour and should not be changed silently.

Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
76d475f2b2 Replace setMultiple() by startTransaction() and commitTransaction()
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
6bf45fb507 A script to list AIO variables that are configurable through aio_variables in community containers
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
c65ccd2db0 Make aio-variables code more robust and psalm-compatible
Now the input gets checked for being useful. It's user-generated data in the
end, which might be "funny" in curious ways.

psalm complained about the possibly unset second array key in the
destructuring assignment of `$key` and `$value`, which won't happen due to the
check for a present equal sign earlier, but nonetheless this way the code is
more robust.

Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
77bec5898f Type for Closure argument
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
662840bc25 Make psalm accept the property-hooks for virtual attributes
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
fd308d4b80 Simplify some code a little bit
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
844831a899 Move handling ENV-var replacement into ConfigurationManger
It's the more appropriate place to have this code, and we had to touch
it anyways to make it assign the values to the attributes.

Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
9c9ad02f8a Set multiple attributes at once
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
c997332e47 Remove residue code
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
f1ffd0771c Privatize GetConfig() and WriteConfig()
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
367e847cc8 Make nextcloud_max_time an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
c1f8ac6989 Make nextcloud_memory_limit an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
3e19fa66d0 Make nextcloud_datadir_mount an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
4de73dd75b Make nextcloud_mount an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
903aed1e34 Make nextcloud_upload_limit an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
96c9c1a6f9 Make talk_port an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
dc28eb6737 Make apache_port an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
4e373cb2f8 Make apache_ip_binding an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
0a22384cd9 Make turn_domain an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
6c04cd055f Make aio_community_containers an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
228440f2a8 Make collabora_additional_options an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
ca35006a85 Make collabora_dictionaries an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
6e5237cd20 Make timezone an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
6033a4486c Make borg_restore_password an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
a361ab9d20 Make borg_remote_repo an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
b4d198f72b Make borg_backup_host_location an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
5b0b9ef826 Make domain an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
f737d2f598 Make isFulltextsearchEnabled an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
f16f5b233d Make isImaginaryEnabled an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
190d47810b Make isTalkRecordingEnabled an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
e009abdd54 Make isTalkEnabled an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:56 +01:00
Pablo Zmdl
cd1c2276e5 Make isCollaboraEnabled an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:51:26 +01:00
Pablo Zmdl
0c3d919618 Make isOnlyofficeEnabled an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:50:34 +01:00
Pablo Zmdl
f8a244bee2 Make isClamavEnabled an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:48:05 +01:00
Pablo Zmdl
bebae7069b Make instance_restore_attempt an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:43:36 +01:00
Pablo Zmdl
f235af29e3 Make isDockerSocketProxyEnabled an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:43:36 +01:00
Pablo Zmdl
6576d3c1e9 Make backupMode an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:43:36 +01:00
Pablo Zmdl
881e77cca5 Make isWhiteboardEnabled an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:43:36 +01:00
Pablo Zmdl
c968e9e310 Make restoreExcludePreviews an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:43:36 +01:00
Pablo Zmdl
b8130958c5 Make selectedRestoreTime an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:43:36 +01:00
Pablo Zmdl
1d11a4682b Make install_latest_major an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:43:36 +01:00
Pablo Zmdl
06fdf31c87 Make AIO_URL an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:43:36 +01:00
Pablo Zmdl
484ff79943 Make wasStartButtonClicked an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:43:36 +01:00
Pablo Zmdl
4d8e959608 Make password an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:43:36 +01:00
Pablo Zmdl
b2f992d955 Make AIO_TOKEN an attribute
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:43:36 +01:00
Pablo Zmdl
a9b648e18f Adapt GetAndGenerateSecret() to get() and set()
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:43:36 +01:00
Pablo Zmdl
21b14a4a5d Adapt GetEnvironmentalVariableOrConfig() to get() and set()
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:43:36 +01:00
Pablo Zmdl
0b6c0733ab Cache config, introduce get() and set() helpers to guide new way to set attributes
Use cached config, use set() for single attributes, setMultiple to wrap
multiple calls to set()

Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
2026-01-28 11:43:36 +01:00
13 changed files with 640 additions and 823 deletions

12
php/composer.lock generated
View file

@ -4058,16 +4058,16 @@
},
{
"name": "symfony/finder",
"version": "v6.4.32",
"version": "v6.4.33",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "3ec24885c1d9ababbb9c8f63bb42fea3c8c9b6de"
"reference": "24965ca011dac87431729640feef8bcf7b5523e0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/3ec24885c1d9ababbb9c8f63bb42fea3c8c9b6de",
"reference": "3ec24885c1d9ababbb9c8f63bb42fea3c8c9b6de",
"url": "https://api.github.com/repos/symfony/finder/zipball/24965ca011dac87431729640feef8bcf7b5523e0",
"reference": "24965ca011dac87431729640feef8bcf7b5523e0",
"shasum": ""
},
"require": {
@ -4102,7 +4102,7 @@
"description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/finder/tree/v6.4.32"
"source": "https://github.com/symfony/finder/tree/v6.4.33"
},
"funding": [
{
@ -4122,7 +4122,7 @@
"type": "tidelift"
}
],
"time": "2026-01-10T14:09:00+00:00"
"time": "2026-01-26T13:03:48+00:00"
},
{
"name": "symfony/polyfill-intl-grapheme",

View file

@ -219,6 +219,7 @@
"SIGNALING_SECRET=%SIGNALING_SECRET%",
"ONLYOFFICE_SECRET=%ONLYOFFICE_SECRET%",
"AIO_URL=%AIO_URL%",
"NC_AIO_VERSION=v%AIO_VERSION%",
"NEXTCLOUD_MOUNT=%NEXTCLOUD_MOUNT%",
"CLAMAV_ENABLED=%CLAMAV_ENABLED%",
"CLAMAV_HOST=nextcloud-aio-clamav",

View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
awk '/^ public [^f][^u][^n]/ { sub(/\$/, "", $3); print $3 }' src/Data/ConfigurationManager.php | sort

View file

@ -20,5 +20,10 @@
</extraFiles>
<issueHandlers>
<ClassMustBeFinal errorLevel="suppress" />
<MissingConstructor>
<errorLevel type="suppress">
<file name="src/Data/ConfigurationManager.php" /> <!-- We're using property hooks with virtual properties in that file, which Psalm wrongly complains about. See <https://github.com/vimeo/psalm/issues/11435>. -->
</errorLevel>
</MissingConstructor>
</issueHandlers>
</psalm>

View file

@ -91,10 +91,10 @@ $app->get('/containers', function (Request $request, Response $response, array $
$skip_domain_validation = isset($params['skip_domain_validation']);
return $view->render($response, 'containers.twig', [
'domain' => $configurationManager->GetDomain(),
'apache_port' => $configurationManager->GetApachePort(),
'borg_backup_host_location' => $configurationManager->GetBorgBackupHostLocation(),
'borg_remote_repo' => $configurationManager->GetBorgRemoteRepo(),
'domain' => $configurationManager->domain,
'apache_port' => $configurationManager->apachePort,
'borg_backup_host_location' => $configurationManager->borgBackupHostLocation,
'borg_remote_repo' => $configurationManager->borgRemoteRepo,
'borg_public_key' => $configurationManager->GetBorgPublicKey(),
'nextcloud_password' => $configurationManager->GetAndGenerateSecret('NEXTCLOUD_PASSWORD'),
'containers' => (new \AIO\ContainerDefinitionFetcher($container->get(\AIO\Data\ConfigurationManager::class), $container))->FetchDefinition(),
@ -103,42 +103,42 @@ $app->get('/containers', function (Request $request, Response $response, array $
'has_backup_run_once' => $configurationManager->hasBackupRunOnce(),
'is_backup_container_running' => $dockerActionManager->isBackupContainerRunning(),
'backup_exit_code' => $dockerActionManager->GetBackupcontainerExitCode(),
'is_instance_restore_attempt' => $configurationManager->isInstanceRestoreAttempt(),
'borg_backup_mode' => $configurationManager->GetBackupMode(),
'was_start_button_clicked' => $configurationManager->wasStartButtonClicked(),
'is_instance_restore_attempt' => $configurationManager->instanceRestoreAttempt,
'borg_backup_mode' => $configurationManager->backupMode,
'was_start_button_clicked' => $configurationManager->wasStartButtonClicked,
'has_update_available' => $dockerActionManager->isAnyUpdateAvailable(),
'last_backup_time' => $configurationManager->GetLastBackupTime(),
'backup_times' => $configurationManager->GetBackupTimes(),
'current_channel' => $dockerActionManager->GetCurrentChannel(),
'is_clamav_enabled' => $configurationManager->isClamavEnabled(),
'is_onlyoffice_enabled' => $configurationManager->isOnlyofficeEnabled(),
'is_collabora_enabled' => $configurationManager->isCollaboraEnabled(),
'is_talk_enabled' => $configurationManager->isTalkEnabled(),
'borg_restore_password' => $configurationManager->GetBorgRestorePassword(),
'is_clamav_enabled' => $configurationManager->isClamavEnabled,
'is_onlyoffice_enabled' => $configurationManager->isOnlyofficeEnabled,
'is_collabora_enabled' => $configurationManager->isCollaboraEnabled,
'is_talk_enabled' => $configurationManager->isTalkEnabled,
'borg_restore_password' => $configurationManager->borgRestorePassword,
'daily_backup_time' => $configurationManager->GetDailyBackupTime(),
'is_daily_backup_running' => $configurationManager->isDailyBackupRunning(),
'timezone' => $configurationManager->GetTimezone(),
'timezone' => $configurationManager->timezone,
'skip_domain_validation' => $configurationManager->shouldDomainValidationBeSkipped($skip_domain_validation),
'talk_port' => $configurationManager->GetTalkPort(),
'collabora_dictionaries' => $configurationManager->GetCollaboraDictionaries(),
'collabora_additional_options' => $configurationManager->GetAdditionalCollaboraOptions(),
'talk_port' => $configurationManager->talkPort,
'collabora_dictionaries' => $configurationManager->collaboraDictionaries,
'collabora_additional_options' => $configurationManager->collaboraAdditionalOptions,
'automatic_updates' => $configurationManager->areAutomaticUpdatesEnabled(),
'is_backup_section_enabled' => $configurationManager->isBackupSectionEnabled(),
'is_imaginary_enabled' => $configurationManager->isImaginaryEnabled(),
'is_fulltextsearch_enabled' => $configurationManager->isFulltextsearchEnabled(),
'is_backup_section_enabled' => !$configurationManager->disableBackupSection,
'is_imaginary_enabled' => $configurationManager->isImaginaryEnabled,
'is_fulltextsearch_enabled' => $configurationManager->isFulltextsearchEnabled,
'additional_backup_directories' => $configurationManager->GetAdditionalBackupDirectoriesString(),
'nextcloud_datadir' => $configurationManager->GetNextcloudDatadirMount(),
'nextcloud_mount' => $configurationManager->GetNextcloudMount(),
'nextcloud_upload_limit' => $configurationManager->GetNextcloudUploadLimit(),
'nextcloud_max_time' => $configurationManager->GetNextcloudMaxTime(),
'nextcloud_memory_limit' => $configurationManager->GetNextcloudMemoryLimit(),
'is_dri_device_enabled' => $configurationManager->isDriDeviceEnabled(),
'is_nvidia_gpu_enabled' => $configurationManager->isNvidiaGpuEnabled(),
'is_talk_recording_enabled' => $configurationManager->isTalkRecordingEnabled(),
'is_docker_socket_proxy_enabled' => $configurationManager->isDockerSocketProxyEnabled(),
'is_whiteboard_enabled' => $configurationManager->isWhiteboardEnabled(),
'nextcloud_datadir' => $configurationManager->nextcloudDatadirMount,
'nextcloud_mount' => $configurationManager->nextcloudMount,
'nextcloud_upload_limit' => $configurationManager->nextcloudUploadLimit,
'nextcloud_max_time' => $configurationManager->nextcloudMaxTime,
'nextcloud_memory_limit' => $configurationManager->nextcloudMemoryLimit,
'is_dri_device_enabled' => $configurationManager->nextcloudEnableDriDevice,
'is_nvidia_gpu_enabled' => $configurationManager->enableNvidiaGpu,
'is_talk_recording_enabled' => $configurationManager->isTalkRecordingEnabled,
'is_docker_socket_proxy_enabled' => $configurationManager->isDockerSocketProxyEnabled,
'is_whiteboard_enabled' => $configurationManager->isWhiteboardEnabled,
'community_containers' => $configurationManager->listAvailableCommunityContainers(),
'community_containers_enabled' => $configurationManager->GetEnabledCommunityContainers(),
'community_containers_enabled' => $configurationManager->aioCommunityContainers,
'bypass_container_update' => $bypass_container_update,
]);
})->setName('profile');

View file

@ -15,11 +15,11 @@ readonly class AuthManager {
}
public function CheckCredentials(string $password) : bool {
return hash_equals($this->configurationManager->GetPassword(), $password);
return hash_equals($this->configurationManager->password, $password);
}
public function CheckToken(string $token) : bool {
return hash_equals($this->configurationManager->GetToken(), $token);
return hash_equals($this->configurationManager->aioToken, $token);
}
public function SetAuthState(bool $isLoggedIn) : void {

View file

@ -41,7 +41,7 @@ readonly class ContainerDefinitionFetcher {
$data = json_decode((string)file_get_contents(DataConst::GetContainersDefinitionPath()), true, 512, JSON_THROW_ON_ERROR);
$additionalContainerNames = [];
foreach ($this->configurationManager->GetEnabledCommunityContainers() as $communityContainer) {
foreach ($this->configurationManager->aioCommunityContainers as $communityContainer) {
if ($communityContainer !== '') {
$path = DataConst::GetCommunityContainersDirectory() . '/' . $communityContainer . '/' . $communityContainer . '.json';
$additionalData = json_decode((string)file_get_contents($path), true, 512, JSON_THROW_ON_ERROR);
@ -56,42 +56,42 @@ readonly class ContainerDefinitionFetcher {
$containers = [];
foreach ($data['aio_services_v1'] as $entry) {
if ($entry['container_name'] === 'nextcloud-aio-clamav') {
if (!$this->configurationManager->isClamavEnabled()) {
if (!$this->configurationManager->isClamavEnabled) {
continue;
}
} elseif ($entry['container_name'] === 'nextcloud-aio-onlyoffice') {
if (!$this->configurationManager->isOnlyofficeEnabled()) {
if (!$this->configurationManager->isOnlyofficeEnabled) {
continue;
}
} elseif ($entry['container_name'] === 'nextcloud-aio-collabora') {
if (!$this->configurationManager->isCollaboraEnabled()) {
if (!$this->configurationManager->isCollaboraEnabled) {
continue;
}
if ($this->configurationManager->isCollaboraSubscriptionEnabled()) {
$entry['image'] = 'ghcr.io/nextcloud-releases/aio-collabora-online';
}
} elseif ($entry['container_name'] === 'nextcloud-aio-talk') {
if (!$this->configurationManager->isTalkEnabled()) {
if (!$this->configurationManager->isTalkEnabled) {
continue;
}
} elseif ($entry['container_name'] === 'nextcloud-aio-talk-recording') {
if (!$this->configurationManager->isTalkRecordingEnabled()) {
if (!$this->configurationManager->isTalkRecordingEnabled) {
continue;
}
} elseif ($entry['container_name'] === 'nextcloud-aio-imaginary') {
if (!$this->configurationManager->isImaginaryEnabled()) {
if (!$this->configurationManager->isImaginaryEnabled) {
continue;
}
} elseif ($entry['container_name'] === 'nextcloud-aio-fulltextsearch') {
if (!$this->configurationManager->isFulltextsearchEnabled()) {
if (!$this->configurationManager->isFulltextsearchEnabled) {
continue;
}
} elseif ($entry['container_name'] === 'nextcloud-aio-docker-socket-proxy') {
if (!$this->configurationManager->isDockerSocketProxyEnabled()) {
if (!$this->configurationManager->isDockerSocketProxyEnabled) {
continue;
}
} elseif ($entry['container_name'] === 'nextcloud-aio-whiteboard') {
if (!$this->configurationManager->isWhiteboardEnabled()) {
if (!$this->configurationManager->isWhiteboardEnabled) {
continue;
}
}
@ -113,34 +113,34 @@ readonly class ContainerDefinitionFetcher {
if (isset($entry['volumes'])) {
foreach ($entry['volumes'] as $value) {
if($value['source'] === '%BORGBACKUP_HOST_LOCATION%') {
$value['source'] = $this->configurationManager->GetBorgBackupHostLocation();
$value['source'] = $this->configurationManager->borgBackupHostLocation;
if($value['source'] === '') {
continue;
}
}
if($value['source'] === '%NEXTCLOUD_MOUNT%') {
$value['source'] = $this->configurationManager->GetNextcloudMount();
$value['source'] = $this->configurationManager->nextcloudMount;
if($value['source'] === '') {
continue;
}
} elseif ($value['source'] === '%NEXTCLOUD_DATADIR%') {
$value['source'] = $this->configurationManager->GetNextcloudDatadirMount();
$value['source'] = $this->configurationManager->nextcloudDatadirMount;
if ($value['source'] === '') {
continue;
}
} elseif ($value['source'] === '%WATCHTOWER_DOCKER_SOCKET_PATH%') {
$value['source'] = $this->configurationManager->GetDockerSocketPath();
$value['source'] = $this->configurationManager->dockerSocketPath;
if($value['source'] === '') {
continue;
}
} elseif ($value['source'] === '%NEXTCLOUD_TRUSTED_CACERTS_DIR%') {
$value['source'] = $this->configurationManager->GetTrustedCacertsDir();
$value['source'] = $this->configurationManager->trustedCacertsDir;
if($value['source'] === '') {
continue;
}
}
if ($value['destination'] === '%NEXTCLOUD_MOUNT%') {
$value['destination'] = $this->configurationManager->GetNextcloudMount();
$value['destination'] = $this->configurationManager->nextcloudMount;
if($value['destination'] === '') {
continue;
}
@ -168,39 +168,39 @@ readonly class ContainerDefinitionFetcher {
}
foreach ($valueDependsOn as $value) {
if ($value === 'nextcloud-aio-clamav') {
if (!$this->configurationManager->isClamavEnabled()) {
if (!$this->configurationManager->isClamavEnabled) {
continue;
}
} elseif ($value === 'nextcloud-aio-onlyoffice') {
if (!$this->configurationManager->isOnlyofficeEnabled()) {
if (!$this->configurationManager->isOnlyofficeEnabled) {
continue;
}
} elseif ($value === 'nextcloud-aio-collabora') {
if (!$this->configurationManager->isCollaboraEnabled()) {
if (!$this->configurationManager->isCollaboraEnabled) {
continue;
}
} elseif ($value === 'nextcloud-aio-talk') {
if (!$this->configurationManager->isTalkEnabled()) {
if (!$this->configurationManager->isTalkEnabled) {
continue;
}
} elseif ($value === 'nextcloud-aio-talk-recording') {
if (!$this->configurationManager->isTalkRecordingEnabled()) {
if (!$this->configurationManager->isTalkRecordingEnabled) {
continue;
}
} elseif ($value === 'nextcloud-aio-imaginary') {
if (!$this->configurationManager->isImaginaryEnabled()) {
if (!$this->configurationManager->isImaginaryEnabled) {
continue;
}
} elseif ($value === 'nextcloud-aio-fulltextsearch') {
if (!$this->configurationManager->isFulltextsearchEnabled()) {
if (!$this->configurationManager->isFulltextsearchEnabled) {
continue;
}
} elseif ($value === 'nextcloud-aio-docker-socket-proxy') {
if (!$this->configurationManager->isDockerSocketProxyEnabled()) {
if (!$this->configurationManager->isDockerSocketProxyEnabled) {
continue;
}
} elseif ($value === 'nextcloud-aio-whiteboard') {
if (!$this->configurationManager->isWhiteboardEnabled()) {
if (!$this->configurationManager->isWhiteboardEnabled) {
continue;
}
}

View file

@ -67,63 +67,34 @@ readonly class ConfigurationController {
}
if (isset($request->getParsedBody()['delete_timezone'])) {
$this->configurationManager->DeleteTimezone();
$this->configurationManager->deleteTimezone();
}
if (isset($request->getParsedBody()['timezone'])) {
$timezone = $request->getParsedBody()['timezone'] ?? '';
$this->configurationManager->SetTimezone($timezone);
$this->configurationManager->timezone = $timezone;
}
if (isset($request->getParsedBody()['options-form'])) {
$officeSuiteChoice = $request->getParsedBody()['office_suite_choice'] ?? '';
if ($officeSuiteChoice === 'collabora') {
$this->configurationManager->SetCollaboraEnabledState(1);
$this->configurationManager->SetOnlyofficeEnabledState(0);
$this->configurationManager->isCollaboraEnabled = true;
$this->configurationManager->isOnlyofficeEnabled = false;
} elseif ($officeSuiteChoice === 'onlyoffice') {
$this->configurationManager->SetCollaboraEnabledState(0);
$this->configurationManager->SetOnlyofficeEnabledState(1);
$this->configurationManager->isCollaboraEnabled = false;
$this->configurationManager->isOnlyofficeEnabled = true;
} else {
$this->configurationManager->SetCollaboraEnabledState(0);
$this->configurationManager->SetOnlyofficeEnabledState(0);
}
if (isset($request->getParsedBody()['clamav'])) {
$this->configurationManager->SetClamavEnabledState(1);
} else {
$this->configurationManager->SetClamavEnabledState(0);
}
if (isset($request->getParsedBody()['talk'])) {
$this->configurationManager->SetTalkEnabledState(1);
} else {
$this->configurationManager->SetTalkEnabledState(0);
}
if (isset($request->getParsedBody()['talk-recording'])) {
$this->configurationManager->SetTalkRecordingEnabledState(1);
} else {
$this->configurationManager->SetTalkRecordingEnabledState(0);
}
if (isset($request->getParsedBody()['imaginary'])) {
$this->configurationManager->SetImaginaryEnabledState(1);
} else {
$this->configurationManager->SetImaginaryEnabledState(0);
}
if (isset($request->getParsedBody()['fulltextsearch'])) {
$this->configurationManager->SetFulltextsearchEnabledState(1);
} else {
$this->configurationManager->SetFulltextsearchEnabledState(0);
}
if (isset($request->getParsedBody()['docker-socket-proxy'])) {
$this->configurationManager->SetDockerSocketProxyEnabledState(1);
} else {
$this->configurationManager->SetDockerSocketProxyEnabledState(0);
}
if (isset($request->getParsedBody()['whiteboard'])) {
$this->configurationManager->SetWhiteboardEnabledState(1);
} else {
$this->configurationManager->SetWhiteboardEnabledState(0);
$this->configurationManager->isCollaboraEnabled = false;
$this->configurationManager->isOnlyofficeEnabled = false;
}
$this->configurationManager->isClamavEnabled = isset($request->getParsedBody()['clamav']);
$this->configurationManager->isTalkEnabled = isset($request->getParsedBody()['talk']);
$this->configurationManager->isTalkRecordingEnabled = isset($request->getParsedBody()['talk-recording']);
$this->configurationManager->isImaginaryEnabled = isset($request->getParsedBody()['imaginary']);
$this->configurationManager->isFulltextsearchEnabled = isset($request->getParsedBody()['fulltextsearch']);
$this->configurationManager->isDockerSocketProxyEnabled = isset($request->getParsedBody()['docker-socket-proxy']);
$this->configurationManager->isWhiteboardEnabled = isset($request->getParsedBody()['whiteboard']);
}
if (isset($request->getParsedBody()['community-form'])) {
@ -137,7 +108,7 @@ readonly class ConfigurationController {
$enabledCC[] = $item;
}
}
$this->configurationManager->SetEnabledCommunityContainers($enabledCC);
$this->configurationManager->aioCommunityContainers = $enabledCC;
}
if (isset($request->getParsedBody()['delete_collabora_dictionaries'])) {
@ -146,16 +117,16 @@ readonly class ConfigurationController {
if (isset($request->getParsedBody()['collabora_dictionaries'])) {
$collaboraDictionaries = $request->getParsedBody()['collabora_dictionaries'] ?? '';
$this->configurationManager->SetCollaboraDictionaries($collaboraDictionaries);
$this->configurationManager->collaboraDictionaries = $collaboraDictionaries;
}
if (isset($request->getParsedBody()['delete_collabora_additional_options'])) {
$this->configurationManager->DeleteAdditionalCollaboraOptions();
$this->configurationManager->deleteAdditionalCollaboraOptions();
}
if (isset($request->getParsedBody()['collabora_additional_options'])) {
$additionalCollaboraOptions = $request->getParsedBody()['collabora_additional_options'] ?? '';
$this->configurationManager->SetAdditionalCollaboraOptions($additionalCollaboraOptions);
$this->configurationManager->collaboraAdditionalOptions = $additionalCollaboraOptions;
}
if (isset($request->getParsedBody()['delete_borg_backup_location_vars'])) {

View file

@ -89,7 +89,7 @@ readonly class DockerController {
}
public function startBackup(bool $forceStopNextcloud = false) : void {
$this->configurationManager->SetBackupMode('backup');
$this->configurationManager->backupMode = 'backup';
$id = self::TOP_CONTAINER;
$this->PerformRecursiveContainerStop($id, $forceStopNextcloud);
@ -109,29 +109,25 @@ readonly class DockerController {
}
public function checkBackup() : void {
$this->configurationManager->SetBackupMode('check');
$this->configurationManager->backupMode = 'check';
$id = 'nextcloud-aio-borgbackup';
$this->PerformRecursiveContainerStart($id);
}
private function listBackup() : void {
$this->configurationManager->SetBackupMode('list');
$this->configurationManager->backupMode = 'list';
$id = 'nextcloud-aio-borgbackup';
$this->PerformRecursiveContainerStart($id);
}
public function StartBackupContainerRestore(Request $request, Response $response, array $args) : Response {
$this->configurationManager->SetBackupMode('restore');
$config = $this->configurationManager->GetConfig();
$config['selected-restore-time'] = $request->getParsedBody()['selected_restore_time'] ?? '';
if (isset($request->getParsedBody()['restore-exclude-previews'])) {
$config['restore-exclude-previews'] = 1;
} else {
$config['restore-exclude-previews'] = '';
}
$this->configurationManager->WriteConfig($config);
$this->configurationManager->startTransaction();
$this->configurationManager->backupMode = 'restore';
$this->configurationManager->selectedRestoreTime = $request->getParsedBody()['selected_restore_time'] ?? '';
$this->configurationManager->restoreExcludePreviews = isset($request->getParsedBody()['restore-exclude-previews']);
$this->configurationManager->commitTransaction();
$id = self::TOP_CONTAINER;
$forceStopNextcloud = true;
@ -144,22 +140,22 @@ readonly class DockerController {
}
public function StartBackupContainerCheckRepair(Request $request, Response $response, array $args) : Response {
$this->configurationManager->SetBackupMode('check-repair');
$this->configurationManager->backupMode = 'check-repair';
$id = 'nextcloud-aio-borgbackup';
$this->PerformRecursiveContainerStart($id);
// Restore to backup check which is needed to make the UI logic work correctly
$this->configurationManager->SetBackupMode('check');
$this->configurationManager->backupMode = 'check';
return $response->withStatus(201)->withHeader('Location', '.');
}
public function StartBackupContainerTest(Request $request, Response $response, array $args) : Response {
$this->configurationManager->SetBackupMode('test');
$config = $this->configurationManager->GetConfig();
$config['instance_restore_attempt'] = 0;
$this->configurationManager->WriteConfig($config);
$this->configurationManager->startTransaction();
$this->configurationManager->backupMode = 'test';
$this->configurationManager->instanceRestoreAttempt = false;
$this->configurationManager->commitTransaction();
$id = self::TOP_CONTAINER;
$this->PerformRecursiveContainerStop($id);
@ -182,20 +178,19 @@ readonly class DockerController {
}
if (isset($request->getParsedBody()['install_latest_major'])) {
$installLatestMajor = 32;
$installLatestMajor = '32';
} else {
$installLatestMajor = "";
$installLatestMajor = '';
}
$config = $this->configurationManager->GetConfig();
$this->configurationManager->startTransaction();
$this->configurationManager->installLatestMajor = $installLatestMajor;
// set AIO_URL
$config['AIO_URL'] = $host . ':' . (string)$port . $path;
$this->configurationManager->aioUrl = $host . ':' . (string)$port . $path;
// set wasStartButtonClicked
$config['wasStartButtonClicked'] = 1;
// set install_latest_major
$config['install_latest_major'] = $installLatestMajor;
$this->configurationManager->WriteConfig($config);
$this->configurationManager->wasStartButtonClicked = true;
$this->configurationManager->commitTransaction();
// Do not pull container images in case 'bypass_container_update' is set via url params
// Needed for local testing
$pullImage = !isset($request->getParsedBody()['bypass_container_update']);
@ -213,10 +208,7 @@ readonly class DockerController {
}
public function startTopContainer(bool $pullImage) : void {
$config = $this->configurationManager->GetConfig();
// set AIO_TOKEN
$config['AIO_TOKEN'] = bin2hex(random_bytes(24));
$this->configurationManager->WriteConfig($config);
$this->configurationManager->aioToken = bin2hex(random_bytes(24));
// Stop domaincheck since apache would not be able to start otherwise
$this->StopDomaincheckContainer();
@ -244,7 +236,7 @@ readonly class DockerController {
// This is a hack but no better solution was found for the meantime
// Stop Collabora first to make sure it force-saves
// See https://github.com/nextcloud/richdocuments/issues/3799
if ($id === self::TOP_CONTAINER && $this->configurationManager->isCollaboraEnabled()) {
if ($id === self::TOP_CONTAINER && $this->configurationManager->isCollaboraEnabled) {
$this->PerformRecursiveContainerStop('nextcloud-aio-collabora');
}
@ -277,7 +269,7 @@ readonly class DockerController {
public function StartDomaincheckContainer() : void
{
# Don't start if domain is already set
if ($this->configurationManager->GetDomain() !== '' || $this->configurationManager->wasStartButtonClicked()) {
if ($this->configurationManager->domain !== '' || $this->configurationManager->wasStartButtonClicked) {
return;
}

File diff suppressed because it is too large Load diff

View file

@ -66,4 +66,8 @@ class DataConst {
public static function GetContainersDefinitionPath() : string {
return (string)realpath(__DIR__ . '/../../containers.json');
}
public static function GetAioVersionFile() : string {
return (string)realpath(__DIR__ . '/../../templates/includes/aio-version.twig');
}
}

View file

@ -17,7 +17,7 @@ readonly class Setup {
}
$password = $this->passwordGenerator->GeneratePassword(8);
$this->configurationManager->SetPassword($password);
$this->configurationManager->password = $password;
return $password;
}

View file

@ -115,9 +115,9 @@ readonly class DockerActionManager {
$containerName = $container->identifier;
$internalPort = $container->internalPorts;
if ($internalPort === '%APACHE_PORT%') {
$internalPort = $this->configurationManager->GetApachePort();
$internalPort = $this->configurationManager->apachePort;
} elseif ($internalPort === '%TALK_PORT%') {
$internalPort = $this->configurationManager->GetTalkPort();
$internalPort = $this->configurationManager->talkPort;
}
if ($internalPort !== "" && $internalPort !== 'host') {
@ -205,7 +205,7 @@ readonly class DockerActionManager {
foreach ($container->volumes->GetVolumes() as $volume) {
// // NEXTCLOUD_MOUNT gets added via bind-mount later on
// if ($container->identifier === 'nextcloud-aio-nextcloud') {
// if ($volume->name === $this->configurationManager->GetNextcloudMount()) {
// if ($volume->name === $this->configurationManager->nextcloudMount) {
// continue;
// }
// }
@ -228,15 +228,7 @@ readonly class DockerActionManager {
$requestBody['HostConfig']['Binds'] = $volumes;
}
$aioVariables = $container->aioVariables->GetVariables();
foreach ($aioVariables as $variable) {
$config = $this->configurationManager->GetConfig();
$variable = $this->replaceEnvPlaceholders($variable);
$variableArray = explode('=', $variable);
$config[$variableArray[0]] = $variableArray[1];
$this->configurationManager->WriteConfig($config);
sleep(1);
}
$this->configurationManager->setAioVariables($container->aioVariables->GetVariables());
$envs = $container->containerEnvironmentVariables->GetVariables();
// Special thing for the nextcloud container
@ -244,7 +236,7 @@ readonly class DockerActionManager {
$envs[] = $this->GetAllNextcloudExecCommands();
}
foreach ($envs as $key => $env) {
$envs[$key] = $this->replaceEnvPlaceholders($env);
$envs[$key] = $this->configurationManager->replaceEnvPlaceholders($env);
}
if (count($envs) > 0) {
@ -261,13 +253,13 @@ readonly class DockerActionManager {
$port = $value->port;
$protocol = $value->protocol;
if ($port === '%APACHE_PORT%') {
$port = $this->configurationManager->GetApachePort();
$port = $this->configurationManager->apachePort;
// Do not expose udp if AIO is in reverse proxy mode
if ($port !== '443' && $protocol === 'udp') {
continue;
}
} else if ($port === '%TALK_PORT%') {
$port = $this->configurationManager->GetTalkPort();
$port = $this->configurationManager->talkPort;
}
$portWithProtocol = $port . '/' . $protocol;
$exposedPorts[$portWithProtocol] = null;
@ -283,13 +275,13 @@ readonly class DockerActionManager {
$port = $value->port;
$protocol = $value->protocol;
if ($port === '%APACHE_PORT%') {
$port = $this->configurationManager->GetApachePort();
$port = $this->configurationManager->apachePort;
// Do not expose udp if AIO is in reverse proxy mode
if ($port !== '443' && $protocol === 'udp') {
continue;
}
} else if ($port === '%TALK_PORT%') {
$port = $this->configurationManager->GetTalkPort();
$port = $this->configurationManager->talkPort;
// Skip publishing talk tcp port if it is set to 443
if ($port === '443' && $protocol === 'tcp') {
continue;
@ -297,7 +289,7 @@ readonly class DockerActionManager {
}
$ipBinding = $value->ipBinding;
if ($ipBinding === '%APACHE_IP_BINDING%') {
$ipBinding = $this->configurationManager->GetApacheIPBinding();
$ipBinding = $this->configurationManager->apacheIpBinding;
// Do not expose if AIO is in internal network mode
if ($ipBinding === '@INTERNAL') {
continue;
@ -315,7 +307,7 @@ readonly class DockerActionManager {
$devices = [];
foreach ($container->devices as $device) {
if ($device === '/dev/dri' && !$this->configurationManager->isDriDeviceEnabled()) {
if ($device === '/dev/dri' && !$this->configurationManager->nextcloudEnableDriDevice) {
continue;
}
$devices[] = ["PathOnHost" => $device, "PathInContainer" => $device, "CgroupPermissions" => "rwm"];
@ -325,7 +317,7 @@ readonly class DockerActionManager {
$requestBody['HostConfig']['Devices'] = $devices;
}
if ($container->enableNvidiaGpu && $this->configurationManager->isNvidiaGpuEnabled()) {
if ($container->enableNvidiaGpu && $this->configurationManager->enableNvidiaGpu) {
$requestBody['HostConfig']['Runtime'] = 'nvidia';
$requestBody['HostConfig']['DeviceRequests'] = [
[
@ -408,7 +400,7 @@ readonly class DockerActionManager {
// // Special things for the nextcloud container which should not be exposed in the containers.json
// } elseif ($container->identifier === 'nextcloud-aio-nextcloud') {
// foreach ($container->volumes->GetVolumes() as $volume) {
// if ($volume->name !== $this->configurationManager->GetNextcloudMount()) {
// if ($volume->name !== $this->configurationManager->nextcloudMount) {
// continue;
// }
// $mounts[] = ["Type" => "bind", "Source" => $volume->name, "Target" => $volume->mountPoint, "ReadOnly" => !$volume->isWritable, "BindOptions" => [ "Propagation" => "rshared"]];
@ -420,15 +412,15 @@ readonly class DockerActionManager {
// Special things for the collabora container which should not be exposed in the containers.json
} elseif ($container->identifier === 'nextcloud-aio-collabora') {
if (!$this->configurationManager->isSeccompDisabled()) {
if (!$this->configurationManager->collaboraSeccompDisabled) {
// Load reference seccomp profile for collabora
$seccompProfile = (string)file_get_contents(DataConst::GetCollaboraSeccompProfilePath());
$requestBody['HostConfig']['SecurityOpt'] = ["label:disable", "seccomp=$seccompProfile"];
}
// Additional Collabora options
if ($this->configurationManager->GetAdditionalCollaboraOptions() !== '') {
$requestBody['Cmd'] = [$this->configurationManager->GetAdditionalCollaboraOptions()];
if ($this->configurationManager->collaboraAdditionalOptions !== '') {
$requestBody['Cmd'] = [$this->configurationManager->collaboraAdditionalOptions];
}
}
@ -530,82 +522,6 @@ readonly class DockerActionManager {
}
}
// Replaces placeholders in $envValue with their values.
// E.g. "%NC_DOMAIN%:%APACHE_PORT" becomes "my.nextcloud.com:11000"
private function replaceEnvPlaceholders(string $envValue): string {
// $pattern breaks down as:
// % - matches a literal percent sign
// ([^%]+) - capture group that matches one or more characters that are NOT percent signs
// % - matches the closing percent sign
//
// Assumes literal percent signs are always matched and there is no
// escaping.
$pattern = '/%([^%]+)%/';
$matchCount = preg_match_all($pattern, $envValue, $matches);
if ($matchCount === 0) {
return $envValue;
}
$placeholders = $matches[0]; // ["%PLACEHOLDER1%", "%PLACEHOLDER2%", ...]
$placeholderNames = $matches[1]; // ["PLACEHOLDER1", "PLACEHOLDER2", ...]
$placeholderPatterns = array_map(static fn(string $p) => '/' . preg_quote($p) . '/', $placeholders); // ["/%PLACEHOLDER1%/", ...]
$placeholderValues = array_map($this->getPlaceholderValue(...), $placeholderNames); // ["val1", "val2"]
// Guaranteed to be non-null because we found the placeholders in the preg_match_all.
return (string) preg_replace($placeholderPatterns, $placeholderValues, $envValue);
}
private function getPlaceholderValue(string $placeholder) : string {
return match ($placeholder) {
'NC_DOMAIN' => $this->configurationManager->GetDomain(),
'NC_BASE_DN' => $this->configurationManager->GetBaseDN(),
'AIO_TOKEN' => $this->configurationManager->GetToken(),
'BORGBACKUP_REMOTE_REPO' => $this->configurationManager->GetBorgRemoteRepo(),
'BORGBACKUP_MODE' => $this->configurationManager->GetBackupMode(),
'AIO_URL' => $this->configurationManager->GetAIOURL(),
'SELECTED_RESTORE_TIME' => $this->configurationManager->GetSelectedRestoreTime(),
'RESTORE_EXCLUDE_PREVIEWS' => $this->configurationManager->GetRestoreExcludePreviews(),
'APACHE_PORT' => $this->configurationManager->GetApachePort(),
'APACHE_IP_BINDING' => $this->configurationManager->GetApacheIPBinding(),
'TALK_PORT' => $this->configurationManager->GetTalkPort(),
'TURN_DOMAIN' => $this->configurationManager->GetTurnDomain(),
'NEXTCLOUD_MOUNT' => $this->configurationManager->GetNextcloudMount(),
'BACKUP_RESTORE_PASSWORD' => $this->configurationManager->GetBorgRestorePassword(),
'CLAMAV_ENABLED' => $this->configurationManager->isClamavEnabled() ? 'yes' : '',
'TALK_RECORDING_ENABLED' => $this->configurationManager->isTalkRecordingEnabled() ? 'yes' : '',
'ONLYOFFICE_ENABLED' => $this->configurationManager->isOnlyofficeEnabled() ? 'yes' : '',
'COLLABORA_ENABLED' => $this->configurationManager->isCollaboraEnabled() ? 'yes' : '',
'TALK_ENABLED' => $this->configurationManager->isTalkEnabled() ? 'yes' : '',
'UPDATE_NEXTCLOUD_APPS' => ($this->configurationManager->isDailyBackupRunning() && $this->configurationManager->areAutomaticUpdatesEnabled()) ? 'yes' : '',
'TIMEZONE' => $this->configurationManager->GetTimezone() === '' ? 'Etc/UTC' : $this->configurationManager->GetTimezone(),
'COLLABORA_DICTIONARIES' => $this->configurationManager->GetCollaboraDictionaries() === '' ? 'de_DE en_GB en_US es_ES fr_FR it nl pt_BR pt_PT ru' : $this->configurationManager->GetCollaboraDictionaries(),
'IMAGINARY_ENABLED' => $this->configurationManager->isImaginaryEnabled() ? 'yes' : '',
'FULLTEXTSEARCH_ENABLED' => $this->configurationManager->isFulltextsearchEnabled() ? 'yes' : '',
'DOCKER_SOCKET_PROXY_ENABLED' => $this->configurationManager->isDockerSocketProxyEnabled() ? 'yes' : '',
'NEXTCLOUD_UPLOAD_LIMIT' => $this->configurationManager->GetNextcloudUploadLimit(),
'NEXTCLOUD_MEMORY_LIMIT' => $this->configurationManager->GetNextcloudMemoryLimit(),
'NEXTCLOUD_MAX_TIME' => $this->configurationManager->GetNextcloudMaxTime(),
'BORG_RETENTION_POLICY' => $this->configurationManager->GetBorgRetentionPolicy(),
'FULLTEXTSEARCH_JAVA_OPTIONS' => $this->configurationManager->GetFulltextsearchJavaOptions(),
'NEXTCLOUD_TRUSTED_CACERTS_DIR' => $this->configurationManager->GetTrustedCacertsDir(),
'ADDITIONAL_DIRECTORIES_BACKUP' => $this->configurationManager->GetAdditionalBackupDirectoriesString() !== '' ? 'yes' : '',
'BORGBACKUP_HOST_LOCATION' => $this->configurationManager->GetBorgBackupHostLocation(),
'APACHE_MAX_SIZE' => (string)($this->configurationManager->GetApacheMaxSize()),
'COLLABORA_SECCOMP_POLICY' => $this->configurationManager->GetCollaboraSeccompPolicy(),
'NEXTCLOUD_STARTUP_APPS' => $this->configurationManager->GetNextcloudStartupApps(),
'NEXTCLOUD_ADDITIONAL_APKS' => $this->configurationManager->GetNextcloudAdditionalApks(),
'NEXTCLOUD_ADDITIONAL_PHP_EXTENSIONS' => $this->configurationManager->GetNextcloudAdditionalPhpExtensions(),
'INSTALL_LATEST_MAJOR' => $this->configurationManager->shouldLatestMajorGetInstalled() ? 'yes' : '',
'REMOVE_DISABLED_APPS' => $this->configurationManager->shouldDisabledAppsGetRemoved() ? 'yes' : '',
// Allow to get local ip-address of database container which allows to talk to it even in host mode (the container that requires this needs to be started first then)
'AIO_DATABASE_HOST' => gethostbyname('nextcloud-aio-database'),
// Allow to get local ip-address of caddy container and add it to trusted proxies automatically
'CADDY_IP_ADDRESS' => in_array('caddy', $this->configurationManager->GetEnabledCommunityContainers(), true) ? gethostbyname('nextcloud-aio-caddy') : '',
'WHITEBOARD_ENABLED' => $this->configurationManager->isWhiteboardEnabled() ? 'yes' : '',
default => $this->configurationManager->GetRegisteredSecret($placeholder),
};
}
private function isContainerUpdateAvailable(string $id): string {
$container = $this->containerDefinitionFetcher->GetContainerById($id);
@ -621,7 +537,7 @@ readonly class DockerActionManager {
public function isAnyUpdateAvailable(): bool {
// return early if instance is not installed
if (!$this->configurationManager->wasStartButtonClicked()) {
if (!$this->configurationManager->wasStartButtonClicked) {
return false;
}
$id = 'nextcloud-aio-apache';
@ -921,7 +837,7 @@ readonly class DockerActionManager {
$this->ConnectContainerIdToNetwork($container->identifier, $container->internalPorts, alias: $alias);
if ($container->identifier === 'nextcloud-aio-apache' || $container->identifier === 'nextcloud-aio-domaincheck') {
$apacheAdditionalNetwork = $this->configurationManager->GetApacheAdditionalNetwork();
$apacheAdditionalNetwork = $this->configurationManager->apacheAdditionalNetwork;
if ($apacheAdditionalNetwork !== '') {
$this->ConnectContainerIdToNetwork($container->identifier, $container->internalPorts, $apacheAdditionalNetwork, false, $alias);
}