Compare commits

..

53 Commits

Author SHA1 Message Date
szaimen
b5e45e270b increase version to v0.8.0
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-16 16:02:01 +01:00
Simon L
1fc8f2dd0f Merge pull request #339 from nextcloud/enh/noid/improve-logging
improve error logging in dockeractionmanager
2022-03-16 15:49:00 +01:00
Julius Härtl
8317b30658 Add error middleware
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2022-03-16 15:43:48 +01:00
szaimen
1a62857df7 improve error logging in dockeractionmanager
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-16 15:43:48 +01:00
szaimen
172ae49cdf improve/fix some things
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-16 14:41:52 +01:00
szaimen
d385d43af0 fix clamav build
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-16 13:38:23 +01:00
Simon L
064ea0f931 Merge pull request #378 from nextcloud/enh/376/add-clamav
add clamav as option
2022-03-16 13:17:33 +01:00
szaimen
7f645b1c1a fix psalm like this as no idea how to fix that
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-16 13:14:05 +01:00
szaimen
38726f039a add clamav as option
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-16 13:14:05 +01:00
Simon L
79fdbee6b4 Merge pull request #347 from nextcloud/enh/noid/move-inline-js-to-file
move inline javascript to its own file
2022-03-16 13:08:51 +01:00
szaimen
4c304d8775 move inline javascript to its own file
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-16 13:07:13 +01:00
Simon L
8a21f2a8f5 Merge pull request #377 from nextcloud/enh/noid/move-mastercontainer
move the mastercontainer section
2022-03-16 13:02:33 +01:00
Simon L
1be6c725c2 Merge pull request #379 from nextcloud/automated/noid/psalm-baseline-update-1647404662
[Automated] Update psalm-baseline.xml
2022-03-16 13:01:19 +01:00
nextcloud-command
c6d40e91e0 Update psalm baseline
Signed-off-by: GitHub <noreply@github.com>
2022-03-16 04:24:21 +00:00
szaimen
4fc4ca1e3e move the mastercontainer section
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-15 19:28:01 +01:00
Simon L
31f86c1570 Merge pull request #375 from nextcloud/enh/374/list-newest-backups-first
list newest backups first
2022-03-15 16:46:42 +01:00
Simon L
a8d380ec7a Merge pull request #370 from nextcloud/enh/noid/allow-upgrades-always
allow to upgrade the mastercontainer even if no update was found
2022-03-15 16:46:34 +01:00
Simon L
6dd88239d1 Merge pull request #372 from nextcloud/enh/noid/restarting-state
allow to check for restarting state
2022-03-15 16:46:02 +01:00
szaimen
ead69baae3 simplify syntax to make it better understandable
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-15 16:30:09 +01:00
szaimen
6be1154914 list newest backups first
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-15 16:02:43 +01:00
Simon L
f9772a856c Merge pull request #373 from nextcloud/aio-dependency-update
Dependency updates
2022-03-15 13:21:54 +01:00
szaimen
83ae27ef76 allow to check for restarting state
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-15 13:19:26 +01:00
szaimen
e60949aec9 dependency updates
Signed-off-by: GitHub <noreply@github.com>
2022-03-15 12:14:50 +00:00
Simon L
817df30465 Merge pull request #352 from nextcloud/enh/fix-domaincheck-startup
fix domaincheck startup
2022-03-15 12:25:55 +01:00
Simon L
07ad9a7eb8 Merge pull request #371 from nextcloud/automated/noid/psalm-baseline-update-1647318331
[Automated] Update psalm-baseline.xml
2022-03-15 10:25:07 +01:00
nextcloud-command
9c96806084 Update psalm baseline
Signed-off-by: GitHub <noreply@github.com>
2022-03-15 04:25:31 +00:00
szaimen
0e1edde3a7 allow to upgrade the mastercontainer even if no update was found
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-14 22:40:13 +01:00
szaimen
8661bdf020 run locking once a day
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-14 20:47:37 +01:00
szaimen
c3579476c6 improve logging of rate limit issues
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-14 17:20:45 +01:00
szaimen
ae349b8afb log if not pulling the latest database image
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-14 17:11:36 +01:00
Simon L
20bf2cfa7e Merge pull request #369 from nextcloud/enh/345/get-caddy-apcu-correctly
get caddy and apcu correctly
2022-03-14 16:43:21 +01:00
Simon L
0cbffeb90a Merge pull request #368 from nextcloud/enh/55/disallow-local-external-storage
Disallow creation of local external storage in some cases
2022-03-14 16:43:13 +01:00
szaimen
8983a97ef6 get caddy and apcu correctly
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-14 16:28:07 +01:00
szaimen
0670c7cedf Disallow creation of local external storage in some cases
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-14 15:35:37 +01:00
Simon L
cd00e5af83 Merge pull request #348 from nextcloud/enh/noid/refactor-some-logic
refactor some config logic
2022-03-14 15:17:48 +01:00
Simon L
2c7146b15f Merge pull request #343 from nextcloud/enh/340/add-headings
add some sensible headings
2022-03-14 15:02:38 +01:00
Simon L
975f4220d4 Merge pull request #338 from nextcloud/enh/noid/domain-change-docs
add docs for how to change domain in button
2022-03-14 15:01:47 +01:00
Simon L
6beaa3b391 Merge pull request #336 from nextcloud/enh/noid/allow-to-get-mastercontainer-logs
allow to get the mastercontainer logs from the frontend
2022-03-14 15:01:08 +01:00
Simon L
6b3cba411e Merge pull request #335 from nextcloud/enh/noid/disallow-database-update-if-failed
correctly disable database update if it failed before
2022-03-14 15:00:55 +01:00
szaimen
ab747de69d adress review
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-14 14:59:46 +01:00
szaimen
480b57178b lock closed issues after 14 days of inactivity
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-13 20:42:39 +01:00
szaimen
c9650aa0ef add issue templates and config
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-13 19:30:10 +01:00
szaimen
0e660f4c04 don't wait for collabora since we might allow to disable it in the future
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-13 18:31:07 +01:00
szaimen
6722dee1d6 fix attempt
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-12 22:50:34 +01:00
szaimen
79af222c2d fix startdomaincheckcontainer logic
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-12 22:50:34 +01:00
szaimen
79473fac76 refactor some config logic
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-11 17:28:55 +01:00
Simon L
9b11c817b2 Merge pull request #344 from nextcloud/dependabot/docker/Containers/mastercontainer/docker-20.10.13-dind-alpine3.15
Bump docker from 20.10.12-dind-alpine3.15 to 20.10.13-dind-alpine3.15 in /Containers/mastercontainer
2022-03-11 13:25:49 +01:00
dependabot[bot]
fb05818764 Bump docker in /Containers/mastercontainer
Bumps docker from 20.10.12-dind-alpine3.15 to 20.10.13-dind-alpine3.15.

---
updated-dependencies:
- dependency-name: docker
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-11 12:23:54 +00:00
szaimen
15a289e820 fix typo in backup script
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-11 09:27:38 +01:00
szaimen
d5868a9626 add some sensible headings
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-11 09:25:38 +01:00
szaimen
22d3b0ba30 allow to get the mastercontainer logs from the frontend
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-09 19:00:04 +01:00
szaimen
2b98a936b9 correctly disable database update if it failed before
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-09 18:31:44 +01:00
szaimen
3263184e8f add docs for how to change domain in button
Signed-off-by: szaimen <szaimen@e.mail.de>
2022-03-09 17:12:16 +01:00
32 changed files with 520 additions and 214 deletions

30
.github/ISSUE_TEMPLATE/Bug_report.md vendored Normal file
View File

@@ -0,0 +1,30 @@
---
name: 🐛 Bug report
about: Help us improving by reporting a bug
labels: bug, 0. Needs triage
---
<!--- Please keep this note for other contributors -->
### How to use GitHub
* Please use the 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to show that you are affected by the same issue.
* Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this issue.
* Subscribe to receive notifications on status change and new comments.
<!--- Please fill out the whole template below -->
### Steps to reproduce
1.
2.
3.
### Expected behaviour <!--- Tell us what should happen -->
### Actual behaviour <!--- Tell us what happens instead -->
---
#### Nextcloud AIO version <!--- (see Nextcloud AIO interface) -->
#### Current channel <!--- (see the channel name in the Mastercontainer section) -->
#### Other valuable info <!--- (like logs, screenshots & Co.) -->

View File

@@ -0,0 +1,24 @@
---
name: 📖 Existing feature/documentation enhancement
about: Suggest an enhancement of an existing feature/documentation - for other types, please use the feature request option below
labels: enhancement, 0. Needs triage
---
<!--- Please keep this note for other contributors -->
### How to use GitHub
* Please use the 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to show that you are interested into the same feature.
* Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this issue.
* Subscribe to receive notifications on status change and new comments.
<!--- Please fill out the whole template below -->
### Is your feature request related to a problem? Please describe.
<!--- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
### Describe the solution you'd like
<!--- A clear and concise description of what you want to happen. -->
### Describe alternatives you've considered
<!--- A clear and concise description of any alternative solutions or features you've considered. -->
#### Additional context
<!--- Add any other context or screenshots about the feature request below. -->

11
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: 💡 Suggest a new feature or discuss one
url: https://github.com/nextcloud/all-in-one/discussions
about: For new feature requests and discussion of existing ones
- name: ❓ Community Support and Help
url: https://help.nextcloud.com/tag/aio
about: For other types of questions
- name: 💼 Nextcloud Enterprise
url: https://portal.nextcloud.com/
about: If you are a Nextcloud Enterprise customer, or need Professional support, so it can be resolved directly by our dedicated engineers more quickly

View File

@@ -108,3 +108,12 @@ updates:
labels:
- 3. to review
- dependencies
- package-ecosystem: "docker"
directory: "/Containers/clamav"
schedule:
interval: "daily"
time: "12:00"
open-pull-requests-limit: 10
labels:
- 3. to review
- dependencies

View File

@@ -31,6 +31,18 @@ jobs:
done
echo "outdated dependencies:
$(composer outdated)"
- name: Update apcu
run: |
# APCU
apcu_version="$(
git ls-remote --tags https://github.com/krakjoe/apcu.git \
| cut -d/ -f3 \
| grep -vE -- '-rc|-b' \
| sed -E 's/^v//' \
| sort -V \
| tail -1
)"
sed -i "s|pecl install APCu.*\;|pecl install APCu-$apcu_version\;|" ./Containers/mastercontainer/Dockerfile
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:

20
.github/workflows/lock-threads.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
name: 'Lock Threads'
on:
schedule:
- cron: '0 0 * * *'
permissions:
issues: write
concurrency:
group: lock
jobs:
action:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v3
with:
issue-inactive-days: '14'
process-only: 'issues'

View File

@@ -1,3 +1,6 @@
# Caddy is a requirement
FROM caddy:2.4.6-alpine as caddy
FROM debian:bullseye-20220228-slim
EXPOSE 80
@@ -21,10 +24,8 @@ RUN set -ex; \
; \
rm -rf /var/lib/apt/lists/*
RUN set -ex; \
wget "https://caddyserver.com/api/download?os=linux&arch=$(dpkg-architecture --query DEB_BUILD_ARCH)" -O "/usr/bin/caddy" \
&& chmod +x /usr/bin/caddy \
&& /usr/bin/caddy version
COPY --from=caddy /usr/bin/caddy /usr/bin/
RUN chmod +x /usr/bin/caddy
RUN a2enmod rewrite \
headers \

View File

@@ -17,12 +17,6 @@ while ! nc -z "$NEXTCLOUD_HOST" 9000; do
sleep 5
done
# Only start container if collabora is started
while ! nc -z "$COLLABORA_HOST" 9980; do
echo "Waiting for Collabora to start..."
sleep 5
done
if [ -z "$APACHE_PORT" ]; then
export APACHE_PORT="443"
fi

View File

@@ -202,7 +202,7 @@ fi
# Do the Backup check
if [ "$BORG_MODE" = check ]; then
get_start_time
echo "Checking the backup integity..."
echo "Checking the backup integrity..."
# Perform the check
if ! borg check --verify-data --progress "$BORG_BACKUP_DIRECTORY"; then

View File

@@ -0,0 +1,5 @@
# Probably from this file: https://github.com/Cisco-Talos/clamav/blob/main/Dockerfile
FROM clamav/clamav:0.104.2-2
COPY clamav.conf /tmp/
RUN cat /tmp/clamav.conf >> /etc/clamav/clamd.conf

View File

@@ -0,0 +1,4 @@
MaxDirectoryRecursion 30
MaxFileSize 100M
PCREMaxFileSize 100M
StreamMaxLength 100M

View File

@@ -1,5 +1,8 @@
# Docker CLI is a requirement
FROM docker:20.10.12-dind-alpine3.15 as dind
FROM docker:20.10.13-dind-alpine3.15 as dind
# Caddy is a requirement
FROM caddy:2.4.6-alpine as caddy
# From https://github.com/docker-library/php/blob/master/8.0/bullseye/apache/Dockerfile
FROM php:8.0.16-apache-bullseye
@@ -26,17 +29,15 @@ RUN apt-get update; \
; \
rm -rf /var/lib/apt/lists/*
RUN set -ex; \
curl "https://caddyserver.com/api/download?os=linux&arch=$(dpkg-architecture --query DEB_BUILD_ARCH)" -o "/usr/bin/caddy" \
&& chmod +x /usr/bin/caddy \
&& /usr/bin/caddy version
COPY --from=caddy /usr/bin/caddy /usr/bin/
RUN chmod +x /usr/bin/caddy
COPY --from=dind /usr/local/bin/docker /usr/local/bin/
RUN chmod +x /usr/local/bin/docker
RUN mkdir -p /usr/src/php/ext/apcu && \
curl -fsSL https://pecl.php.net/get/apcu | tar xvz -C "/usr/src/php/ext/apcu" --strip 1 && \
docker-php-ext-install apcu
RUN set -ex; \
pecl install APCu-5.1.21; \
docker-php-ext-enable apcu
RUN set -e && \
curl -sS https://getcomposer.org/installer | php && \

View File

@@ -251,6 +251,13 @@ php /var/www/html/occ config:system:set overwrite.cli.url --value="https://$NC_D
php /var/www/html/occ config:system:set htaccess.RewriteBase --value="/"
php /var/www/html/occ maintenance:update:htaccess
# Disallow creating local external storages when nothing was mounted
if [ -z "$NEXTCLOUD_MOUNT" ]; then
php /var/www/html/occ config:system:set files_external_allow_create_new_local --type=bool --value=false
else
php /var/www/html/occ config:system:set files_external_allow_create_new_local --type=bool --value=true
fi
# AIO app
if [ "$(php /var/www/html/occ config:app:get nextcloud-aio enabled)" = "" ]; then
php /var/www/html/occ app:enable nextcloud-aio
@@ -297,5 +304,26 @@ php /var/www/html/occ config:app:set spreed stun_servers --value="$STUN_SERVERS"
php /var/www/html/occ config:app:set spreed turn_servers --value="$TURN_SERVERS" --output json
php /var/www/html/occ config:app:set spreed signaling_servers --value="$SIGNALING_SERVERS" --output json
# Clamav
if [ "$CLAMAV_ENABLED" = 'yes' ]; then
if ! [ -d "/var/www/html/custom_apps/files_antivirus" ]; then
php /var/www/html/occ app:install files_antivirus
elif [ "$(php /var/www/html/occ config:app:get files_antivirus enabled)" = "no" ]; then
php /var/www/html/occ app:enable files_antivirus
else
php /var/www/html/occ app:update files_antivirus
fi
php /var/www/html/occ config:app:set files_antivirus av_mode --value="daemon"
php /var/www/html/occ config:app:set files_antivirus av_port --value="3310"
php /var/www/html/occ config:app:set files_antivirus av_host --value="$CLAMAV_HOST"
php /var/www/html/occ config:app:set files_antivirus av_stream_max_length --value="104857600"
php /var/www/html/occ config:app:set files_antivirus av_max_file_size --value="-1"
php /var/www/html/occ config:app:set files_antivirus av_infected_action --value="only_log"
else
if [ -d "/var/www/html/custom_apps/files_antivirus" ]; then
php /var/www/html/occ app:remove files_antivirus
fi
fi
# Remove the update skip file always
rm -f /mnt/ncdata/skip.update

22
php/composer.lock generated
View File

@@ -1192,22 +1192,22 @@
},
{
"name": "slim/slim",
"version": "4.9.0",
"version": "4.10.0",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Slim.git",
"reference": "44d3c9c0bfcc47e52e42b097b6062689d21b904b"
"reference": "0dfc7d2fdf2553b361d864d51af3fe8a6ad168b0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/slimphp/Slim/zipball/44d3c9c0bfcc47e52e42b097b6062689d21b904b",
"reference": "44d3c9c0bfcc47e52e42b097b6062689d21b904b",
"url": "https://api.github.com/repos/slimphp/Slim/zipball/0dfc7d2fdf2553b361d864d51af3fe8a6ad168b0",
"reference": "0dfc7d2fdf2553b361d864d51af3fe8a6ad168b0",
"shasum": ""
},
"require": {
"ext-json": "*",
"nikic/fast-route": "^1.3",
"php": "^7.3 || ^8.0",
"php": "^7.4 || ^8.0",
"psr/container": "^1.0 || ^2.0",
"psr/http-factory": "^1.0",
"psr/http-message": "^1.0",
@@ -1218,13 +1218,15 @@
"require-dev": {
"adriansuter/php-autoload-override": "^1.2",
"ext-simplexml": "*",
"guzzlehttp/psr7": "^2.0",
"guzzlehttp/psr7": "^2.1",
"httpsoft/http-message": "^1.0",
"httpsoft/http-server-request": "^1.0",
"laminas/laminas-diactoros": "^2.8",
"nyholm/psr7": "^1.4",
"nyholm/psr7": "^1.5",
"nyholm/psr7-server": "^1.0",
"phpspec/prophecy": "^1.14",
"phpspec/prophecy": "^1.15",
"phpspec/prophecy-phpunit": "^2.0",
"phpstan/phpstan": "^0.12.99",
"phpstan/phpstan": "^1.4",
"phpunit/phpunit": "^9.5",
"slim/http": "^1.2",
"slim/psr7": "^1.5",
@@ -1301,7 +1303,7 @@
"type": "tidelift"
}
],
"time": "2021-10-05T03:00:00+00:00"
"time": "2022-03-14T14:18:23+00:00"
},
{
"name": "slim/twig-view",

View File

@@ -4,7 +4,8 @@
"dependsOn": [
"nextcloud-aio-nextcloud",
"nextcloud-aio-collabora",
"nextcloud-aio-talk"
"nextcloud-aio-talk",
"nextcloud-aio-clamav"
],
"identifier": "nextcloud-aio-apache",
"displayName": "Apache",
@@ -122,7 +123,10 @@
"OVERWRITEPROTOCOL=https",
"TURN_SECRET=%TURN_SECRET%",
"SIGNALING_SECRET=%SIGNALING_SECRET%",
"AIO_URL=%AIO_URL%"
"AIO_URL=%AIO_URL%",
"NEXTCLOUD_MOUNT=%NEXTCLOUD_MOUNT%",
"CLAMAV_ENABLED=%CLAMAV_ENABLED%",
"CLAMAV_HOST=nextcloud-aio-clamav"
],
"maxShutdownTime": 10,
"restartPolicy": "unless-stopped"
@@ -291,6 +295,27 @@
],
"maxShutdownTime": 1,
"restartPolicy": ""
},
{
"dependsOn": [],
"identifier": "nextcloud-aio-clamav",
"displayName": "ClamAV",
"containerName": "nextcloud/aio-clamav",
"ports": [],
"internalPorts": [
"3310"
],
"environmentVariables": [],
"volumes": [
{
"name": "nextcloud_aio_clamav",
"location": "/var/lib/clamav",
"writeable": true
}
],
"secrets": [],
"maxShutdownTime": 10,
"restartPolicy": "unless-stopped"
}
]
}

View File

@@ -18,17 +18,21 @@
<MissingParamType occurrences="1">
<code>$args</code>
</MissingParamType>
<PossiblyInvalidArrayAccess occurrences="2">
<PossiblyInvalidArrayAccess occurrences="4">
<code>$request-&gt;getParsedBody()['borg_backup_host_location']</code>
<code>$request-&gt;getParsedBody()['domain']</code>
<code>$request-&gt;getParsedBody()['clamav']</code>
<code>$request-&gt;getParsedBody()['options-form']</code>
</PossiblyInvalidArrayAccess>
<PossiblyNullArgument occurrences="2">
<code>$request-&gt;getParsedBody()['borg_backup_host_location']</code>
<code>$request-&gt;getParsedBody()['domain']</code>
</PossiblyNullArgument>
<PossiblyNullArrayAccess occurrences="2">
<PossiblyNullArrayAccess occurrences="4">
<code>$request-&gt;getParsedBody()['borg_backup_host_location']</code>
<code>$request-&gt;getParsedBody()['domain']</code>
<code>$request-&gt;getParsedBody()['clamav']</code>
<code>$request-&gt;getParsedBody()['options-form']</code>
</PossiblyNullArrayAccess>
</file>
<file src="src/Controller/DockerController.php">
@@ -44,19 +48,9 @@
<PossiblyInvalidArrayAccess occurrences="1">
<code>$request-&gt;getParsedBody()['selected_restore_time']</code>
</PossiblyInvalidArrayAccess>
<PossiblyNullArgument occurrences="1">
<code>$container</code>
</PossiblyNullArgument>
<PossiblyNullArrayAccess occurrences="1">
<code>$request-&gt;getParsedBody()['selected_restore_time']</code>
</PossiblyNullArrayAccess>
<PossiblyNullReference occurrences="5">
<code>GetDependsOn</code>
<code>GetDependsOn</code>
<code>GetIdentifier</code>
<code>GetIdentifier</code>
<code>GetRunningState</code>
</PossiblyNullReference>
</file>
<file src="src/Controller/LoginController.php">
<MissingParamType occurrences="3">
@@ -74,12 +68,6 @@
<code>$request-&gt;getParsedBody()['password']</code>
</PossiblyNullArrayAccess>
</file>
<file src="src/Cron/cron.php">
<PossiblyNullArgument occurrences="2">
<code>$nextcloudContainer</code>
<code>$nextcloudContainer</code>
</PossiblyNullArgument>
</file>
<file src="src/Docker/DockerActionManager.php">
<InvalidReturnType occurrences="1">
<code>IContainerState</code>
@@ -90,12 +78,6 @@
<PossiblyFalseOperand occurrences="1">
<code>strpos($fullDigest, "@")</code>
</PossiblyFalseOperand>
<PossiblyNullArgument occurrences="1">
<code>$apacheContainer</code>
</PossiblyNullArgument>
<PossiblyNullReference occurrences="1">
<code>GetUpdateState</code>
</PossiblyNullReference>
<RedundantCondition occurrences="1">
<code>$container-&gt;GetInternalPorts() !== null</code>
</RedundantCondition>

View File

@@ -0,0 +1,13 @@
if (document.hasFocus()) {
// hide reload button if the site reloads automatically
var list = document.getElementsByClassName("reload button");
for (var i = 0; i < list.length; i++) {
// list[i] is a node with the desired class name
list[i].style.display = 'none';
}
// set timeout for reload
setTimeout(function(){
window.location.reload(1);
}, 5000);
}

View File

@@ -0,0 +1,5 @@
document.addEventListener("DOMContentLoaded", function(event) {
// Clamav
var clamav = document.getElementById("clamav");
clamav.disabled = true;
});

View File

@@ -48,6 +48,7 @@ $app->add(new \AIO\Middleware\AuthMiddleware($container->get(\AIO\Auth\AuthManag
// API
$app->post('/api/docker/watchtower', AIO\Controller\DockerController::class . ':StartWatchtowerContainer');
$app->get('/api/docker/getwatchtower', AIO\Controller\DockerController::class . ':StartWatchtowerContainer');
$app->post('/api/docker/start', AIO\Controller\DockerController::class . ':StartContainer');
$app->post('/api/docker/backup', AIO\Controller\DockerController::class . ':StartBackupContainerBackup');
$app->post('/api/docker/backup-check', AIO\Controller\DockerController::class . ':StartBackupContainerCheck');
@@ -84,6 +85,8 @@ $app->get('/containers', function ($request, $response, $args) use ($container)
'last_backup_time' => $configurationManager->GetLastBackupTime(),
'backup_times' => $configurationManager->GetBackupTimes(),
'current_channel' => $dockerActionManger->GetCurrentChannel(),
'is_x64_platform' => $configurationManager->isx64Platform(),
'is_clamav_enabled' => $configurationManager->isClamavEnabled(),
]);
})->setName('profile');
$app->get('/login', function ($request, $response, $args) use ($container) {
@@ -138,4 +141,6 @@ $app->get('/', function (\Psr\Http\Message\RequestInterface $request, \Psr\Http\
}
});
$errorMiddleware = $app->addErrorMiddleware(true, true, true);
$app->run();

View File

@@ -0,0 +1,14 @@
function makeOptionsFormSubmitVisible() {
var optionsFormSubmit = document.getElementById("options-form-submit");
optionsFormSubmit.style.display = 'block';
}
document.addEventListener("DOMContentLoaded", function(event) {
// handle submit button for options form
var optionsFormSubmit = document.getElementById("options-form-submit");
optionsFormSubmit.style.display = 'none';
// Clamav
var clamav = document.getElementById("clamav");
clamav.addEventListener('change', makeOptionsFormSubmitVisible);
});

View File

@@ -91,6 +91,10 @@ class Container {
return $this->dockerActionManager->GetContainerRunningState($this);
}
public function GetRestartingState() : IContainerState {
return $this->dockerActionManager->GetContainerRestartingState($this);
}
public function GetUpdateState() : IContainerState {
return $this->dockerActionManager->GetContainerUpdateState($this);
}

View File

@@ -0,0 +1,6 @@
<?php
namespace AIO\Container\State;
class NotRestartingState implements IContainerState
{}

View File

@@ -0,0 +1,6 @@
<?php
namespace AIO\Container\State;
class RestartingState implements IContainerState
{}

View File

@@ -27,7 +27,7 @@ class ContainerDefinitionFetcher
$this->container = $container;
}
public function GetContainerById(string $id): ?Container
public function GetContainerById(string $id): Container
{
$containers = $this->FetchDefinition();
@@ -37,7 +37,7 @@ class ContainerDefinitionFetcher
}
}
return null;
throw new \Exception("The provided id " . $id . " was not found in the container definition.");
}
/**
@@ -49,6 +49,12 @@ class ContainerDefinitionFetcher
$containers = [];
foreach ($data['production'] as $entry) {
if ($entry['identifier'] === 'nextcloud-aio-clamav') {
if (!$this->configurationManager->isClamavEnabled()) {
continue;
}
}
$ports = new ContainerPorts();
foreach ($entry['ports'] as $port) {
if($port === '%APACHE_PORT%/tcp') {
@@ -99,6 +105,16 @@ class ContainerDefinitionFetcher
);
}
$dependsOn = [];
foreach ($entry['dependsOn'] as $value) {
if ($value === 'nextcloud-aio-clamav') {
if (!$this->configurationManager->isClamavEnabled()) {
continue;
}
}
$dependsOn[] = $value;
}
$variables = new ContainerEnvironmentVariables();
foreach ($entry['environmentVariables'] as $value) {
$variables->AddVariable($value);
@@ -114,7 +130,7 @@ class ContainerDefinitionFetcher
$internalPorts,
$volumes,
$variables,
$entry['dependsOn'],
$dependsOn,
$entry['secrets'],
$this->container->get(DockerActionManager::class)
);

View File

@@ -35,6 +35,14 @@ class ConfigurationController
$this->configurationManager->SetBorgBackupHostLocation($request->getParsedBody()['borg_backup_host_location']);
}
if (isset($request->getParsedBody()['options-form'])) {
if (isset($request->getParsedBody()['clamav'])) {
$this->configurationManager->SetClamavEnabledState(1);
} else {
$this->configurationManager->SetClamavEnabledState(0);
}
}
return $response->withStatus(201)->withHeader('Location', '/');
} catch (InvalidSettingConfigurationException $ex) {
$response->getBody()->write($ex->getMessage());

View File

@@ -33,9 +33,19 @@ class DockerController
$this->PerformRecursiveContainerStart($dependency);
}
$pullcontainer = true;
if ($id === 'nextcloud-aio-database') {
if ($this->dockerActionManager->GetDatabasecontainerExitCode() > 0) {
$pullcontainer = false;
}
}
$this->dockerActionManager->DeleteContainer($container);
$this->dockerActionManager->CreateVolumes($container);
$this->dockerActionManager->PullContainer($container);
if ($pullcontainer) {
$this->dockerActionManager->PullContainer($container);
} else {
error_log('Not pulling the latest database image because the container was not correctly shut down.');
}
$this->dockerActionManager->CreateContainer($container);
$this->dockerActionManager->StartContainer($container);
$this->dockerActionManager->ConnectContainerToNetwork($container);
@@ -44,8 +54,12 @@ class DockerController
public function GetLogs(Request $request, Response $response, $args) : Response
{
$id = $request->getQueryParams()['id'];
$container = $this->containerDefinitionFetcher->GetContainerById($id);
$logs = $this->dockerActionManager->GetLogs($container);
if (str_starts_with($id, 'nextcloud-aio-')) {
$logs = $this->dockerActionManager->GetLogs($id);
} else {
$logs = 'Container not found.';
}
$body = $response->getBody();
$body->write($logs);
@@ -149,22 +163,32 @@ class DockerController
public function StartDomaincheckContainer() : void
{
# Don't start if domain is already set
if ($this->configurationManager->GetDomain() != '') {
if ($this->configurationManager->GetDomain() !== '' || $this->configurationManager->wasStartButtonClicked()) {
return;
}
$id = 'nextcloud-aio-domaincheck';
$container = $this->containerDefinitionFetcher->GetContainerById($id);
// don't start if the domaincheck is already running
if ($container->GetIdentifier() === $id && $container->GetRunningState() instanceof RunningState) {
return;
// don't start if apache is already running
} elseif ($container->GetIdentifier() === self::TOP_CONTAINER && $container->GetRunningState() instanceof RunningState) {
$cacheKey = 'domaincheckWasStarted';
$domaincheckContainer = $this->containerDefinitionFetcher->GetContainerById($id);
$apacheContainer = $this->containerDefinitionFetcher->GetContainerById(self::TOP_CONTAINER);
// Don't start if apache is already running
if ($apacheContainer->GetRunningState() instanceof RunningState) {
return;
// Don't start if domaincheck is already running
} elseif ($domaincheckContainer->GetRunningState() instanceof RunningState) {
$domaincheckWasStarted = apcu_fetch($cacheKey);
// Start domaincheck again when 10 minutes are over by not returning here
if($domaincheckWasStarted !== false && is_string($domaincheckWasStarted)) {
return;
}
}
$this->PerformRecursiveContainerStart($id);
// Cache the start for 10 minutes
apcu_add($cacheKey, '1', 600);
}
private function StopDomaincheckContainer() : void

View File

@@ -102,6 +102,9 @@ class ConfigurationManager
}
}
// Reverse the array to list newest backup first
$backupTimes = array_reverse($backupTimes);
return $backupTimes;
}
@@ -113,6 +116,29 @@ class ConfigurationManager
}
}
public function isx64Platform() : bool {
if (php_uname('m') === 'x86_64') {
return true;
} else {
return false;
}
}
public function isClamavEnabled() : bool {
$config = $this->GetConfig();
if (isset($config['isClamavEnabled']) && $config['isClamavEnabled'] === 1) {
return true;
} else {
return false;
}
}
public function SetClamavEnabledState(int $value) : void {
$config = $this->GetConfig();
$config['isClamavEnabled'] = $value;
$this->WriteConfig($config);
}
/**
* @throws InvalidSettingConfigurationException
*/
@@ -265,26 +291,10 @@ class ConfigurationManager
}
public function GetApachePort() : string {
$port = getenv('APACHE_PORT');
if ($port === false) {
$config = $this->GetConfig();
if (!isset($config['apache_port']) || $config['apache_port'] === '') {
$config['apache_port'] = '443';
}
return $config['apache_port'];
} else {
if(file_exists(DataConst::GetConfigFile())) {
$config = $this->GetConfig();
if (!isset($config['apache_port'])) {
$config['apache_port'] = '';
}
if ($port !== $config['apache_port']) {
$config['apache_port'] = $port;
$this->WriteConfig($config);
}
}
return $port;
}
$envVariableName = 'APACHE_PORT';
$configName = 'apache_port';
$defaultValue = '443';
return $this->GetEnvironmentalVariableOrConfig($envVariableName, $configName, $defaultValue);
}
/**
@@ -297,6 +307,28 @@ class ConfigurationManager
file_put_contents(DataConst::GetConfigFile(), json_encode($config));
}
private function GetEnvironmentalVariableOrConfig(string $envVariableName, string $configName, string $defaultValue) : string {
$envVariableOutput = getenv($envVariableName);
if ($envVariableOutput === false) {
$config = $this->GetConfig();
if (!isset($config[$configName]) || $config[$configName] === '') {
$config[$configName] = $defaultValue;
}
return $config[$configName];
}
if(file_exists(DataConst::GetConfigFile())) {
$config = $this->GetConfig();
if (!isset($config[$configName])) {
$config[$configName] = '';
}
if ($envVariableOutput !== $config[$configName]) {
$config[$configName] = $envVariableOutput;
$this->WriteConfig($config);
}
}
return $envVariableOutput;
}
public function GetBorgBackupHostLocation() : string {
$config = $this->GetConfig();
if(!isset($config['borg_backup_host_location'])) {
@@ -316,48 +348,16 @@ class ConfigurationManager
}
public function GetNextcloudMount() : string {
$mount = getenv('NEXTCLOUD_MOUNT');
if ($mount === false) {
$config = $this->GetConfig();
if (!isset($config['nextcloud_mount'])) {
$config['nextcloud_mount'] = '';
}
return $config['nextcloud_mount'];
} else {
if(file_exists(DataConst::GetConfigFile())) {
$config = $this->GetConfig();
if (!isset($config['nextcloud_mount'])) {
$config['nextcloud_mount'] = '';
}
if ($mount !== $config['nextcloud_mount']) {
$config['nextcloud_mount'] = $mount;
$this->WriteConfig($config);
}
}
return $mount;
}
$envVariableName = 'NEXTCLOUD_MOUNT';
$configName = 'nextcloud_mount';
$defaultValue = '';
return $this->GetEnvironmentalVariableOrConfig($envVariableName, $configName, $defaultValue);
}
public function GetNextcloudDatadirMount() : string {
$mount = getenv('NEXTCLOUD_DATADIR');
if ($mount === false) {
$config = $this->GetConfig();
if (!isset($config['nextcloud_datadir']) || $config['nextcloud_datadir'] === '') {
$config['nextcloud_datadir'] = 'nextcloud_aio_nextcloud_data';
}
return $config['nextcloud_datadir'];
} else {
if(file_exists(DataConst::GetConfigFile())) {
$config = $this->GetConfig();
if (!isset($config['nextcloud_datadir'])) {
$config['nextcloud_datadir'] = '';
}
if ($mount !== $config['nextcloud_datadir']) {
$config['nextcloud_datadir'] = $mount;
$this->WriteConfig($config);
}
}
return $mount;
}
$envVariableName = 'NEXTCLOUD_DATADIR';
$configName = 'nextcloud_datadir';
$defaultValue = 'nextcloud_aio_nextcloud_data';
return $this->GetEnvironmentalVariableOrConfig($envVariableName, $configName, $defaultValue);
}
}

View File

@@ -7,6 +7,8 @@ use AIO\Container\State\IContainerState;
use AIO\Container\State\ImageDoesNotExistState;
use AIO\Container\State\StartingState;
use AIO\Container\State\RunningState;
use AIO\Container\State\RestartingState;
use AIO\Container\State\NotRestartingState;
use AIO\Container\State\VersionDifferentState;
use AIO\Container\State\StoppedState;
use AIO\Container\State\VersionEqualState;
@@ -70,6 +72,27 @@ class DockerActionManager
}
}
public function GetContainerRestartingState(Container $container) : IContainerState
{
$url = $this->BuildApiUrl(sprintf('containers/%s/json', urlencode($container->GetIdentifier())));
try {
$response = $this->guzzleClient->get($url);
} catch (RequestException $e) {
if ($e->getCode() === 404) {
return new ImageDoesNotExistState();
}
throw $e;
}
$responseBody = json_decode((string)$response->getBody(), true);
if ($responseBody['State']['Restarting'] === true) {
return new RestartingState();
} else {
return new NotRestartingState();
}
}
public function GetContainerUpdateState(Container $container) : IContainerState
{
$tag = $this->GetCurrentChannel();
@@ -120,12 +143,12 @@ class DockerActionManager
}
}
public function GetLogs(Container $container) : string
public function GetLogs(string $id) : string
{
$url = $this->BuildApiUrl(
sprintf(
'containers/%s/logs?stdout=true&stderr=true',
urlencode($container->GetIdentifier())
urlencode($id)
));
$responseBody = (string)$this->guzzleClient->get($url)->getBody();
@@ -216,6 +239,14 @@ class DockerActionManager
$replacements[1] = $this->configurationManager->GetSelectedRestoreTime();
} elseif ($out[1] === 'APACHE_PORT') {
$replacements[1] = $this->configurationManager->GetApachePort();
} elseif ($out[1] === 'NEXTCLOUD_MOUNT') {
$replacements[1] = $this->configurationManager->GetNextcloudMount();
} elseif ($out[1] === 'CLAMAV_ENABLED') {
if ($this->configurationManager->isClamavEnabled()) {
$replacements[1] = 'yes';
} else {
$replacements[1] = '';
}
} else {
$replacements[1] = $this->configurationManager->GetSecret($out[1]);
}
@@ -250,30 +281,30 @@ class DockerActionManager
}
$url = $this->BuildApiUrl('containers/create?name=' . $container->GetIdentifier());
$this->guzzleClient->request(
'POST',
$url,
[
'json' => $requestBody
]
);
try {
$this->guzzleClient->request(
'POST',
$url,
[
'json' => $requestBody
]
);
} catch (RequestException $e) {
throw $e;
}
}
public function PullContainer(Container $container) : void
{
$pullcontainer = true;
if ($container->GetIdentifier() === 'nextcloud-aio-database') {
if ($this->GetDatabasecontainerExitCode() > 0) {
$pullcontainer = false;
}
}
if ($pullcontainer) {
$url = $this->BuildApiUrl(sprintf('images/create?fromImage=%s', urlencode($this->BuildImageName($container))));
try {
$this->guzzleClient->post($url);
} catch (RequestException $e) {
throw $e;
}
$url = $this->BuildApiUrl(sprintf('images/create?fromImage=%s', urlencode($this->BuildImageName($container))));
try {
$this->guzzleClient->post($url);
} catch (RequestException $e) {
error_log('Could not get image ' . $this->BuildImageName($container) . ' from docker hub. Probably due to rate limits. ' . $e->getMessage());
// Don't exit here because it is possible that the image is already present
// and we ran into docker hub limits.
// We will exit later if not image should be available.
}
}
@@ -318,6 +349,7 @@ class DockerActionManager
return null;
} catch (\Exception $e) {
error_log('Could not get digest of container ' . $this->BuildApiUrl($containerName) . ' ' . $e->getMessage());
return null;
}
}
@@ -339,6 +371,7 @@ class DockerActionManager
apcu_add($cacheKey, $tag);
return $tag;
} catch (\Exception $e) {
error_log('Could not get current channel ' . $e->getMessage());
}
return 'latest';
@@ -425,6 +458,7 @@ class DockerActionManager
]
);
} catch (RequestException $e) {
error_log('Could not disconnect container from network ' . $e->getMessage());
}
}

View File

@@ -23,6 +23,8 @@ class DockerHubManager
return $cachedVersion;
}
// If one of the links below should ever become outdated, we can still upgrade the mastercontainer via the webinterface manually by opening '/api/docker/getwatchtower'
try {
$authTokenRequest = $this->guzzleClient->request(
'GET',

View File

@@ -16,10 +16,11 @@
</header>
<div class="content">
<h1>Nextcloud AIO Beta v0.7.0</h1>
<h1>Nextcloud AIO Beta v0.8.0</h1>
This is beta software and not production ready.<br><br>
{% set isAnyRunning = false %}
{% set isAnyRestarting = false %}
{% set isWatchtowerRunning = false %}
{% set isBackupContainerRunning = false %}
{% set isRestoreRunning = false %}
@@ -27,9 +28,12 @@
{% set isApacheStarting = false %}
{% for container in containers %}
{% if class(container.GetRunningState()) == 'AIO\\Container\\State\\RunningState' and container.GetIdentifier() != 'nextcloud-aio-domaincheck' and container.GetIdentifier() != 'nextcloud-aio-borgbackup' and container.GetIdentifier() != 'nextcloud-aio-watchtower' %}
{% if container.GetIdentifier() not in ['nextcloud-aio-domaincheck', 'nextcloud-aio-borgbackup', 'nextcloud-aio-watchtower'] and class(container.GetRunningState()) == 'AIO\\Container\\State\\RunningState' %}
{% set isAnyRunning = true %}
{% endif %}
{% if container.GetIdentifier() in ['nextcloud-aio-redis', 'nextcloud-aio-database', 'nextcloud-aio-nextcloud', 'nextcloud-aio-apache'] and class(container.GetRestartingState()) == 'AIO\\Container\\State\\RestartingState' %}
{% set isAnyRestarting = true %}
{% endif %}
{% if container.GetIdentifier() == 'nextcloud-aio-watchtower' and class(container.GetRunningState()) == 'AIO\\Container\\State\\RunningState' %}
{% set isWatchtowerRunning = true %}
{% endif %}
@@ -77,13 +81,22 @@
{% if isAnyRunning == true %}
{% if isApacheStarting != true %}
Your initial Nextcloud credentials:<br><br />
Initial Nextcloud username: admin<br />
Initial Nextcloud password: {{ nextcloud_password }}<br /><br/>
<a href="https://{{ domain }}" class="button" target="_blank" rel="noopener">Open your Nextcloud ↗</a><br/>
{% else %}
Containers are currently starting.<br /><br />
<a href="" class="button reload">Reload ↻</a><br/>
{% if isAnyRestarting == false %}
Containers are currently starting.<br /><br />
<a href="" class="button reload">Reload ↻</a><br/><br>
{% else %}
It seems like at least one container is currently restarting which means it is not able to start correctly.<br><br>
To break out this endless loop, you can stop the containers below and investigate the issue by having a look at the container logs before starting them again.<br><br>
<form method="POST" action="/api/docker/stop" class="xhr">
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
<input class="button" type="submit" value="Stop containers" />
</form>
{% endif %}
{% endif %}
{% endif %}
@@ -92,7 +105,7 @@
<ul>
{# @var containers \AIO\Container\Container[] #}
{% for container in containers %}
{% if container.GetIdentifier() != 'nextcloud-aio-borgbackup' and container.GetIdentifier() != 'nextcloud-aio-watchtower' and container.GetIdentifier() != 'nextcloud-aio-domaincheck' %}
{% if container.GetIdentifier() not in ['nextcloud-aio-borgbackup', 'nextcloud-aio-watchtower', 'nextcloud-aio-domaincheck'] %}
<li>
{% if class(container.GetStartingState()) == 'AIO\\Container\\State\\StartingState' %}
<span class="status running"></span>
@@ -111,7 +124,7 @@
{% if has_update_available == true %}
{% if is_mastercontainer_update_available == false %}
⚠ Container updates are available. Click on `Stop Containers` and `Start Containers` to update them. You should consider creating a backup first.<br><br>
⚠ Container updates are available. Click on 'Stop Containers' and 'Start Containers' to update them. You should consider creating a backup first.<br><br>
{% endif %}
{% else %}
{% if is_mastercontainer_update_available == false %}
@@ -141,7 +154,7 @@
Clicking on the button below will download all docker containers and start them. This can take a lot of time depending on your internect connection. Since the overall size is a few GB, this will take around 5-10 min or more. So be aware and patient!<br><br>
{% endif %}
{% if is_mastercontainer_update_available == true %}
⚠ Please update your mastercontainer. Afterwards, you will be able to start your containers again.<br><br>
⚠ Please update your mastercontainer. (The update button is in the Mastercontainer section below the Backup section. Click <a href="#mastercontainer"><b>here</b><a/> to go there.) Afterwards, you will be able to start your containers again.<br><br>
{% else %}
{% if was_start_button_clicked == false or has_update_available == false %}
<form method="POST" action="/api/docker/start" class="xhr">
@@ -161,42 +174,6 @@
{% endif %}
{% if was_start_button_clicked == true %}
{% if isBackupOrRestoreRunning == false %}
<h2>Mastercontainer</h2>
You are currently running the {{ current_channel }} channel.<br><br>
{% if is_mastercontainer_update_available == true %}
{% if isAnyRunning == false %}
⚠ A mastercontainer update is available. Please click on the button below to update it.<br><br>
<form method="POST" action="/api/docker/watchtower" class="xhr">
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
<input class="button" type="submit" value="Update mastercontainer" />
</form>
{% else %}
⚠ A mastercontainer update is available. Please stop your containers in order to be able to update the mastercontainer.<br><br>
{% endif %}
{% if current_channel starts with 'latest' %}
You can find the changelog <a href="https://github.com/nextcloud/all-in-one/releases/latest">here</a><br><br>
{% elseif current_channel starts with 'beta' %}
You can find the changelog <a href="https://github.com/nextcloud/all-in-one/releases">here</a><br><br>
{% elseif current_channel starts with 'develop' %}
You can find all changes <a href="https://github.com/nextcloud-releases/all-in-one/commits/main">here</a><br><br>
{% endif %}
{% endif %}
{% if isApacheStarting == false %}
You can change your AIO password below:<br><br />
<form method="POST" action="/api/configuration" class="xhr">
<input type="text" autocomplete="current-password" name="current-master-password" placeholder="your current aio password"/>
<input type="text" autocomplete="new-password" name="new-master-password" placeholder="your new aio password"/>
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
<input class="button" type="submit" value="Submit" />
</form>
The new password needs to be at least 24 characters long. Allowed characters are the <a href="https://en.wikipedia.org/wiki/Latin_alphabet#/media/File:Abecedarium.png">latin characters</a> 'a-z', 'A-Z', '0-9' and spaces.<br><br>
{% endif %}
{% endif %}
{% if isBackupOrRestoreRunning == false and borg_backup_host_location == "" and isApacheStarting != true %}
<h2>Backup and restore</h2>
@@ -225,6 +202,7 @@
{% endif %}
{% if isBackupContainerRunning == false %}
<h3>Backup information</h3>
This is your encryption password for backups: {{ borgbackup_password }} <br /><br/>
Please save it at a safe place since you won't be able to restore from backup if you loose this password! <br /><br/>
Backed up will get all important data of your Nextcloud AIO instance like the database, your files and configuration files of the mastercontainer and else. <br /><br/>
@@ -233,6 +211,8 @@
Be aware that this solution does not back up files and folders that are mounted into Nextcloud using the external storage app. <br /><br/>
{% if isApacheStarting != true %}
<h3>Backup creation</h3>
Clicking on the button below will create a backup.<br><br/>
<form method="POST" action="/api/docker/backup" class="xhr">
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
@@ -240,6 +220,7 @@
</form>
{% if has_backup_run_once == true %}
<h3>Backup check</h3>
Click on the button below to perform a backup integrity check. This is an option that verifies that your backup is intact but it should't be needed in most situtations.<br><br/>
<form method="POST" action="/api/docker/backup-check" class="xhr">
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
@@ -247,6 +228,7 @@
<input class="button" type="submit" value="Check backup integrity" onclick="return confirm('Check backup integrity? Are you sure that you want to check the backup? This can take a long time depending on the size of your backup.')" /><br/>
</form>
<h3>Backup restore</h3>
Choose the backup that you want to restore and click on the button below to restore the selected backup. This will overwrite all your files with the state of the backup so you should consider creating a backup first. It also makes sense to run an integrity check before restoring your files but is not mandatory since it shouldn't be needed in most situations.<br><br>
<form method="POST" action="/api/docker/restore" class="xhr" id="restore_selection">
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
@@ -266,30 +248,68 @@
<a href="" class="button reload">Reload ↻</a><br/>
{% endif %}
{% endif %}
{% if isBackupContainerRunning == false %}
<h2 id="mastercontainer">Mastercontainer</h2>
You are currently running the {{ current_channel }} channel. (<a href="/api/docker/logs?id=nextcloud-aio-mastercontainer">Logs</a>)<br><br>
{% if is_mastercontainer_update_available == true %}
{% if isAnyRunning == false %}
⚠ A mastercontainer update is available. Please click on the button below to update it.<br><br>
<form method="POST" action="/api/docker/watchtower" class="xhr">
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
<input class="button" type="submit" value="Update mastercontainer" />
</form>
{% else %}
⚠ A mastercontainer update is available. Please stop your containers in order to be able to update the mastercontainer.<br><br>
{% endif %}
{% if current_channel starts with 'latest' %}
You can find the changelog <a href="https://github.com/nextcloud/all-in-one/releases/latest">here</a><br><br>
{% elseif current_channel starts with 'beta' %}
You can find the changelog <a href="https://github.com/nextcloud/all-in-one/releases">here</a><br><br>
{% elseif current_channel starts with 'develop' %}
You can find all changes <a href="https://github.com/nextcloud-releases/all-in-one/commits/main">here</a><br><br>
{% endif %}
{% endif %}
{% if isApacheStarting == false %}
<h3>AIO password change</h3>
You can change your AIO password below:<br><br />
<form method="POST" action="/api/configuration" class="xhr">
<input type="text" autocomplete="current-password" name="current-master-password" placeholder="your current aio password"/>
<input type="text" autocomplete="new-password" name="new-master-password" placeholder="your new aio password"/>
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
<input class="button" type="submit" value="Submit" />
</form>
The new password needs to be at least 24 characters long. Allowed characters are the <a href="https://en.wikipedia.org/wiki/Latin_alphabet#/media/File:Abecedarium.png">latin characters</a> 'a-z', 'A-Z', '0-9' and spaces.<br><br>
{% endif %}
{% endif %}
{% endif %}
{% if isBackupContainerRunning == false %}
<h2>Optional</h2>
In this section, you can find optional addons.<br><br>
You can change the state of them when your containers are stopped.<br><br>
<form id="options-form" method="POST" action="/api/configuration" class="xhr">
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
<input type="hidden" name="options-form" value="options-form">
{% if is_clamav_enabled == true %}
<input type="checkbox" id="clamav" name="clamav" checked="checked"><label for="clamav">ClamAV (only supported on x64, needs ~2GB additional RAM)</label>
{% else %}
<input type="checkbox" id="clamav" name="clamav"><label for="clamav">ClamAV (only supported on x64, needs ~2GB additional RAM)</label>
{% endif %}
<input id="options-form-submit" class="button" type="submit" value="Save changes" />
</form>
{% if isAnyRunning == true or is_x64_platform == false %}
<script type="text/javascript" src="disable-clamav.js"></script>
{% endif %}
{% endif %}
<h2>Optional</h2>
In this section, you will find optional addons in the future.
It will disable the ability to change them when any containers are running and allow to change them when they are stopped.
Also, it will display possible sections for optional addons. (which itself will be displayed when enabled and running).
{% endif %}
{% endif %}
{% if isApacheStarting == true or isBackupContainerRunning == true or isWatchtowerRunning == true %}
<script>
if (document.hasFocus()) {
// hide reload button if the site reloads automatically
var list = document.getElementsByClassName("reload button");
for (var i = 0; i < list.length; i++) {
// list[i] is a node with the desired class name
list[i].style.display = 'none';
}
// set timeout for reload
setTimeout(function(){
window.location.reload(1);
}, 5000);
}
</script>
<script type="text/javascript" src="automatic_reload.js"></script>
{% endif %}
</div>

View File

@@ -4,6 +4,7 @@
<link rel="stylesheet" href="/style.css" media="all" />
<link rel="icon" href="/img/favicon.png">
<script type="text/javascript" src="forms.js"></script>
<script type="text/javascript" src="options-form-submit.js"></script>
</head>
<body>

View File

@@ -104,7 +104,7 @@ If a new `Mastercontainer` update was found, you'll see an additional section be
Additionally, there is a cronjob that runs once a day that checks for container and mastercontainer updates and sends a notification to all Nextcloud admins if a new update was found.
### How to easily log in to the AIO interface?
If your Nextcloud is running and you are logged in as admin in your Nextcloud, you can easily log in to the AIO interface by opening `https://yourdomain.tld/settings/admin/overview` which will show a button on top that enables you to log in to the AIO interface by just clicking on this button.
If your Nextcloud is running and you are logged in as admin in your Nextcloud, you can easily log in to the AIO interface by opening `https://yourdomain.tld/settings/admin/overview` which will show a button on top that enables you to log in to the AIO interface by just clicking on this button. **Note:** You can change the domain/ip-address/port of the button by simply stopping the containers, visiting the AIO interface from the correct and desired domain/ip-address/port and clicking once on `Start containers`.
### Backup solution
Nextcloud AIO provides a local backup solution based on BorgBackup. These backups act as a local restore point in case the installation gets corrupted.