Compare commits

..

1 Commits

Author SHA1 Message Date
Jean-Yves
161d8820fe nextcloud/coding-standard
Signed-off-by: Jean-Yves <7360784+docjyJ@users.noreply.github.com>
2024-10-04 20:27:21 +02:00
37 changed files with 526 additions and 157 deletions

52
.github/workflows/lint-php-cs.yml vendored Normal file
View File

@@ -0,0 +1,52 @@
# This workflow is provided via the organization template repository
#
# https://github.com/nextcloud/.github
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
#
# SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: MIT
name: Lint php-cs
on:
pull_request:
paths:
- 'php/**'
push:
branches:
- main
paths:
- 'php/**'
permissions:
contents: read
concurrency:
group: lint-php-cs-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
lint:
runs-on: ubuntu-latest
strategy:
matrix:
php-versions: [ "8.3" ]
name: php-cs
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Set up php ${{ matrix.php-versions }}
uses: shivammathur/setup-php@a4e22b60bbb9c1021113f2860347b0759f66fe5d # v2
with:
php-version: ${{ matrix.php-versions }}
coverage: none
ini-file: development
- name: Install dependencies
run: cd php && composer i
- name: Lint
run: cd php && composer run cs:check || ( echo 'Please run `composer run cs:fix` to format your code' && exit 1 )

3
.gitignore vendored
View File

@@ -6,7 +6,8 @@
/php/session/*
!/php/data/.gitkeep
!/php/session/.gitkeep
/php/vendor
/php/vendor/
/php/.php-cs-fixer.cache
/manual-install/*.conf
!/manual-install/sample.conf

View File

@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:latest
# Probably from this file: https://github.com/Cisco-Talos/clamav-docker/blob/main/clamav/1.3/alpine/Dockerfile
FROM clamav/clamav:1.4.1-7
FROM clamav/clamav:1.4.1-5
COPY clamav.conf /clamav.conf
COPY --chmod=775 start.script /start.script

View File

@@ -1,7 +1,7 @@
# syntax=docker/dockerfile:latest
FROM golang:1.23.2-alpine3.20 AS go
ENV IMAGINARY_HASH=8f36a26c448be8c151a3878404b75fcd1cd3cf0c
ENV IMAGINARY_HASH=6cd9edd1d3fb151eb773c14552886e4fc8e50138
RUN set -ex; \
apk add --no-cache \

View File

@@ -8,7 +8,7 @@ ENV SOURCE_LOCATION=/usr/src/nextcloud
ENV REDIS_DB_INDEX=0
# AIO settings start # Do not remove or change this line!
ENV NEXTCLOUD_VERSION=29.0.8
ENV NEXTCLOUD_VERSION=29.0.7
ENV AIO_TOKEN=123456
ENV AIO_URL=localhost
# AIO settings end # Do not remove or change this line!
@@ -81,7 +81,7 @@ RUN set -ex; \
pecl install igbinary-3.2.16; \
pecl install APCu-5.1.24; \
pecl install -D 'enable-memcached-igbinary="yes"' memcached-3.2.0; \
pecl install -D 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"' redis-6.1.0; \
pecl install -D 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-lz4="yes"' redis-6.0.2; \
pecl install imagick-3.7.0; \
\
docker-php-ext-enable \

View File

@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:latest
# From https://github.com/docker-library/redis/blob/master/7.2/alpine/Dockerfile
FROM redis:7.2.6-alpine
FROM redis:7.2.5-alpine
COPY --chmod=775 start.sh /start.sh

View File

@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:latest
FROM python:3.13.0-alpine3.20
FROM python:3.12.7-alpine3.20
COPY --chmod=775 start.sh /start.sh

View File

@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:latest
FROM ghcr.io/nextcloud-releases/whiteboard:v1.0.3
FROM ghcr.io/nextcloud-releases/whiteboard:v1.0.2
USER root
RUN set -ex; \

View File

@@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
require_once './vendor/autoload.php';
use Nextcloud\CodingStandard\Config;
$config = new Config();
$config
->getFinder()
->ignoreVCSIgnored(true)
->notPath('data')
->notPath('session')
->notPath('public')
->notPath('vendor')
->in(__DIR__);
return $config;

View File

@@ -21,10 +21,12 @@
"require-dev": {
"sserbin/twig-linter": "@dev",
"vimeo/psalm": "^5.25",
"wapmorgan/php-deprecation-detector": "dev-master"
"wapmorgan/php-deprecation-detector": "dev-master",
"nextcloud/coding-standard": "^1.3",
"friendsofphp/php-cs-fixer": "^3"
},
"scripts": {
"dev": [
"dev": [
"Composer\\Config::disableProcessTimeout",
"php -S localhost:8080 -t public"
],
@@ -33,6 +35,8 @@
"psalm:strict": "psalm --threads=1 --show-info=true",
"lint": "php -l src/*.php src/**/*.php public/index.php",
"lint:twig": "twig-linter lint ./templates",
"cs:check": "php-cs-fixer fix --dry-run --diff",
"cs:fix": "php-cs-fixer fix",
"php-deprecation-detector": "phpdd scan -n -t 8.3 src/*.php src/**/*.php public/index.php"
}
}

142
php/composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "0e1d24f3fa776163acefdebc91da39d3",
"content-hash": "b8bd0cb88d1582f9c4118112a24ac215",
"packages": [
{
"name": "guzzlehttp/guzzle",
@@ -2416,6 +2416,52 @@
],
"time": "2024-08-06T10:04:20+00:00"
},
{
"name": "kubawerlos/php-cs-fixer-custom-fixers",
"version": "v3.22.0",
"source": {
"type": "git",
"url": "https://github.com/kubawerlos/php-cs-fixer-custom-fixers.git",
"reference": "8701394f0c7cd450ac4fa577d24589122c1d5d5e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/kubawerlos/php-cs-fixer-custom-fixers/zipball/8701394f0c7cd450ac4fa577d24589122c1d5d5e",
"reference": "8701394f0c7cd450ac4fa577d24589122c1d5d5e",
"shasum": ""
},
"require": {
"ext-filter": "*",
"ext-tokenizer": "*",
"friendsofphp/php-cs-fixer": "^3.61.1",
"php": "^7.4 || ^8.0"
},
"require-dev": {
"phpunit/phpunit": "^9.6.4 || ^10.5.29"
},
"type": "library",
"autoload": {
"psr-4": {
"PhpCsFixerCustomFixers\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Kuba Werłos",
"email": "werlos@gmail.com"
}
],
"description": "A set of custom fixers for PHP CS Fixer",
"support": {
"issues": "https://github.com/kubawerlos/php-cs-fixer-custom-fixers/issues",
"source": "https://github.com/kubawerlos/php-cs-fixer-custom-fixers/tree/v3.22.0"
},
"time": "2024-08-16T20:44:35+00:00"
},
{
"name": "netresearch/jsonmapper",
"version": "v4.5.0",
@@ -2467,6 +2513,48 @@
},
"time": "2024-09-08T10:13:13+00:00"
},
{
"name": "nextcloud/coding-standard",
"version": "v1.3.1",
"source": {
"type": "git",
"url": "https://github.com/nextcloud/coding-standard.git",
"reference": "e88acb0df6217b808d1632286ddfec9267a102e4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nextcloud/coding-standard/zipball/e88acb0df6217b808d1632286ddfec9267a102e4",
"reference": "e88acb0df6217b808d1632286ddfec9267a102e4",
"shasum": ""
},
"require": {
"kubawerlos/php-cs-fixer-custom-fixers": "^3.22",
"php": "^7.3|^8.0",
"php-cs-fixer/shim": "^3.17"
},
"type": "library",
"autoload": {
"psr-4": {
"Nextcloud\\CodingStandard\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Christoph Wurst",
"email": "christoph@winzerhof-wurst.at"
}
],
"description": "Nextcloud coding standards for the php cs fixer",
"support": {
"issues": "https://github.com/nextcloud/coding-standard/issues",
"source": "https://github.com/nextcloud/coding-standard/tree/v1.3.1"
},
"time": "2024-09-19T09:07:10+00:00"
},
{
"name": "nikic/php-parser",
"version": "v4.19.4",
@@ -2523,6 +2611,58 @@
},
"time": "2024-09-29T15:01:53+00:00"
},
{
"name": "php-cs-fixer/shim",
"version": "v3.64.0",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/shim.git",
"reference": "81ccfd24baf3a10810dab1152c403981a790b837"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/shim/zipball/81ccfd24baf3a10810dab1152c403981a790b837",
"reference": "81ccfd24baf3a10810dab1152c403981a790b837",
"shasum": ""
},
"require": {
"ext-json": "*",
"ext-tokenizer": "*",
"php": "^7.4 || ^8.0"
},
"replace": {
"friendsofphp/php-cs-fixer": "self.version"
},
"suggest": {
"ext-dom": "For handling output formats in XML",
"ext-mbstring": "For handling non-UTF8 characters."
},
"bin": [
"php-cs-fixer",
"php-cs-fixer.phar"
],
"type": "application",
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Dariusz Rumiński",
"email": "dariusz.ruminski@gmail.com"
}
],
"description": "A tool to automatically fix PHP code style",
"support": {
"issues": "https://github.com/PHP-CS-Fixer/shim/issues",
"source": "https://github.com/PHP-CS-Fixer/shim/tree/v3.64.0"
},
"time": "2024-08-30T23:10:11+00:00"
},
{
"name": "phpdocumentor/reflection-common",
"version": "2.2.0",

View File

@@ -6,12 +6,12 @@ use AIO\Data\ConfigurationManager;
use AIO\Data\DataConst;
use \DateTime;
readonly class AuthManager {
class AuthManager {
private const string SESSION_KEY = 'aio_authenticated';
private ConfigurationManager $configurationManager;
public function __construct(
private ConfigurationManager $configurationManager
) {
public function __construct(ConfigurationManager $configurationManager) {
$this->configurationManager = $configurationManager;
}
public function CheckCredentials(string $password) : bool {

View File

@@ -2,42 +2,92 @@
namespace AIO\Container;
use AIO\Container\State\IContainerState;
use AIO\Data\ConfigurationManager;
use AIO\Docker\DockerActionManager;
use AIO\ContainerDefinitionFetcher;
readonly class Container {
class Container {
private string $identifier;
private string $displayName;
private string $containerName;
private string $restartPolicy;
private int $maxShutdownTime;
private ContainerPorts $ports;
private string $internalPorts;
private ContainerVolumes $volumes;
private ContainerEnvironmentVariables $containerEnvironmentVariables;
/** @var string[] */
private array $dependsOn;
/** @var string[] */
private array $secrets;
/** @var string[] */
private array $devices;
/** @var string[] */
private array $capAdd;
private int $shmSize;
private bool $apparmorUnconfined;
/** @var string[] */
private array $backupVolumes;
private array $nextcloudExecCommands;
private bool $readOnlyRootFs;
private array $tmpfs;
private bool $init;
private string $imageTag;
private AioVariables $aioVariables;
private string $documentation;
private DockerActionManager $dockerActionManager;
public function __construct(
private string $identifier,
private string $displayName,
private string $containerName,
private string $restartPolicy,
private int $maxShutdownTime,
private ContainerPorts $ports,
private string $internalPorts,
private ContainerVolumes $volumes,
private ContainerEnvironmentVariables $containerEnvironmentVariables,
/** @var string[] */
private array $dependsOn,
/** @var string[] */
private array $secrets,
/** @var string[] */
private array $devices,
/** @var string[] */
private array $capAdd,
private int $shmSize,
private bool $apparmorUnconfined,
/** @var string[] */
private array $backupVolumes,
private array $nextcloudExecCommands,
private bool $readOnlyRootFs,
private array $tmpfs,
private bool $init,
private string $imageTag,
private AioVariables $aioVariables,
private string $documentation,
private DockerActionManager $dockerActionManager
string $identifier,
string $displayName,
string $containerName,
string $restartPolicy,
int $maxShutdownTime,
ContainerPorts $ports,
string $internalPorts,
ContainerVolumes $volumes,
ContainerEnvironmentVariables $containerEnvironmentVariables,
array $dependsOn,
array $secrets,
array $devices,
array $capAdd,
int $shmSize,
bool $apparmorUnconfined,
array $backupVolumes,
array $nextcloudExecCommands,
bool $readOnlyRootFs,
array $tmpfs,
bool $init,
string $imageTag,
AioVariables $aioVariables,
string $documentation,
DockerActionManager $dockerActionManager
) {
$this->identifier = $identifier;
$this->displayName = $displayName;
$this->containerName = $containerName;
$this->restartPolicy = $restartPolicy;
$this->maxShutdownTime = $maxShutdownTime;
$this->ports = $ports;
$this->internalPorts = $internalPorts;
$this->volumes = $volumes;
$this->containerEnvironmentVariables = $containerEnvironmentVariables;
$this->dependsOn = $dependsOn;
$this->secrets = $secrets;
$this->devices = $devices;
$this->capAdd = $capAdd;
$this->shmSize = $shmSize;
$this->apparmorUnconfined = $apparmorUnconfined;
$this->backupVolumes = $backupVolumes;
$this->nextcloudExecCommands = $nextcloudExecCommands;
$this->readOnlyRootFs = $readOnlyRootFs;
$this->tmpfs = $tmpfs;
$this->init = $init;
$this->imageTag = $imageTag;
$this->aioVariables = $aioVariables;
$this->documentation = $documentation;
$this->dockerActionManager = $dockerActionManager;
}
public function GetIdentifier() : string {
@@ -112,19 +162,19 @@ readonly class Container {
return $this->volumes;
}
public function GetRunningState() : ContainerState {
public function GetRunningState() : IContainerState {
return $this->dockerActionManager->GetContainerRunningState($this);
}
public function GetRestartingState() : ContainerState {
public function GetRestartingState() : IContainerState {
return $this->dockerActionManager->GetContainerRestartingState($this);
}
public function GetUpdateState() : VersionState {
public function GetUpdateState() : IContainerState {
return $this->dockerActionManager->GetContainerUpdateState($this);
}
public function GetStartingState() : ContainerState {
public function GetStartingState() : IContainerState {
return $this->dockerActionManager->GetContainerStartingState($this);
}

View File

@@ -3,10 +3,17 @@
namespace AIO\Container;
class ContainerPort {
public string $port;
public string $ipBinding;
public string $protocol;
public function __construct(
public string $port,
public string $ipBinding,
public string $protocol
string $port,
string $ipBinding,
string $protocol
) {
$this->port = $port;
$this->ipBinding = $ipBinding;
$this->protocol = $protocol;
}
}

View File

@@ -1,12 +0,0 @@
<?php
namespace AIO\Container;
enum ContainerState: string {
case ImageDoesNotExist = 'image_does_not_exist';
case NotRestarting = 'not_restarting';
case Restarting = 'restarting';
case Running = 'running';
case Starting = 'starting';
case Stopped = 'stopped';
}

View File

@@ -3,10 +3,17 @@
namespace AIO\Container;
class ContainerVolume {
public string $name;
public string $mountPoint;
public bool $isWritable;
public function __construct(
public string $name,
public string $mountPoint,
public bool $isWritable
string $name,
string $mountPoint,
bool $isWritable
) {
$this->name = $name;
$this->mountPoint = $mountPoint;
$this->isWritable = $isWritable;
}
}

View File

@@ -0,0 +1,5 @@
<?php
namespace AIO\Container\State;
interface IContainerState {}

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,8 +0,0 @@
<?php
namespace AIO\Container;
enum VersionState: string {
case Different = 'different';
case Equal = 'equal';
}

View File

@@ -9,15 +9,23 @@ use AIO\Container\ContainerPort;
use AIO\Container\ContainerPorts;
use AIO\Container\ContainerVolume;
use AIO\Container\ContainerVolumes;
use AIO\Container\State\RunningState;
use AIO\Data\ConfigurationManager;
use AIO\Data\DataConst;
use AIO\Docker\DockerActionManager;
readonly class ContainerDefinitionFetcher {
class ContainerDefinitionFetcher
{
private ConfigurationManager $configurationManager;
private \DI\Container $container;
public function __construct(
private ConfigurationManager $configurationManager,
private \DI\Container $container
) {
ConfigurationManager $configurationManager,
\DI\Container $container
)
{
$this->configurationManager = $configurationManager;
$this->container = $container;
}
public function GetContainerById(string $id): Container
@@ -95,7 +103,7 @@ readonly class ContainerDefinitionFetcher {
$ports = new ContainerPorts();
if (isset($entry['ports'])) {
foreach ($entry['ports'] as $value) {
foreach ($entry['ports'] as $value) {
$ports->AddPort(
new ContainerPort(
$value['port_number'],
@@ -204,7 +212,7 @@ readonly class ContainerDefinitionFetcher {
$dependsOn[] = $value;
}
}
$variables = new ContainerEnvironmentVariables();
if (isset($entry['environment'])) {
foreach ($entry['environment'] as $value) {

View File

@@ -9,10 +9,14 @@ use AIO\Docker\DockerActionManager;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
readonly class ConfigurationController {
class ConfigurationController
{
private ConfigurationManager $configurationManager;
public function __construct(
private ConfigurationManager $configurationManager
ConfigurationManager $configurationManager
) {
$this->configurationManager = $configurationManager;
}
public function SetConfig(Request $request, Response $response, array $args) : Response {

View File

@@ -2,21 +2,28 @@
namespace AIO\Controller;
use AIO\Container\ContainerState;
use AIO\Container\State\RunningState;
use AIO\ContainerDefinitionFetcher;
use AIO\Docker\DockerActionManager;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use AIO\Data\ConfigurationManager;
readonly class DockerController {
class DockerController
{
private DockerActionManager $dockerActionManager;
private ContainerDefinitionFetcher $containerDefinitionFetcher;
private const string TOP_CONTAINER = 'nextcloud-aio-apache';
private ConfigurationManager $configurationManager;
public function __construct(
private DockerActionManager $dockerActionManager,
private ContainerDefinitionFetcher $containerDefinitionFetcher,
private ConfigurationManager $configurationManager
DockerActionManager $dockerActionManager,
ContainerDefinitionFetcher $containerDefinitionFetcher,
ConfigurationManager $configurationManager
) {
$this->dockerActionManager = $dockerActionManager;
$this->containerDefinitionFetcher = $containerDefinitionFetcher;
$this->configurationManager = $configurationManager;
}
private function PerformRecursiveContainerStart(string $id, bool $pullImage = true) : void {
@@ -28,7 +35,7 @@ readonly class DockerController {
// Don't start if container is already running
// This is expected to happen if a container is defined in depends_on of multiple containers
if ($container->GetRunningState() === ContainerState::Running) {
if ($container->GetRunningState() instanceof RunningState) {
error_log('Not starting ' . $id . ' because it was already started.');
return;
}
@@ -41,7 +48,7 @@ readonly class DockerController {
}
}
// Check if docker hub is reachable in order to make sure that we do not try to pull an image if it is down
// Check if docker hub is reachable in order to make sure that we do not try to pull an image if it is down
// and try to mitigate issues that are arising due to that
if ($pullImage) {
if (!$this->dockerActionManager->isDockerHubReachable($container)) {
@@ -254,10 +261,10 @@ readonly class DockerController {
$domaincheckContainer = $this->containerDefinitionFetcher->GetContainerById($id);
$apacheContainer = $this->containerDefinitionFetcher->GetContainerById(self::TOP_CONTAINER);
// Don't start if apache is already running
if ($apacheContainer->GetRunningState() === ContainerState::Running) {
if ($apacheContainer->GetRunningState() instanceof RunningState) {
return;
// Don't start if domaincheck is already running
} elseif ($domaincheckContainer->GetRunningState() === ContainerState::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)) {

View File

@@ -9,11 +9,14 @@ use AIO\Docker\DockerActionManager;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
readonly class LoginController {
public function __construct(
private AuthManager $authManager,
private DockerActionManager $dockerActionManager,
) {
class LoginController
{
private AuthManager $authManager;
private DockerActionManager $dockerActionManager;
public function __construct(AuthManager $authManager, DockerActionManager $dockerActionManager) {
$this->authManager = $authManager;
$this->dockerActionManager = $dockerActionManager;
}
public function TryLogin(Request $request, Response $response, array $args) : Response {

View File

@@ -4,11 +4,16 @@ namespace AIO\Data;
use AIO\Auth\PasswordGenerator;
readonly class Setup {
class Setup
{
private PasswordGenerator $passwordGenerator;
private ConfigurationManager $configurationManager;
public function __construct(
private PasswordGenerator $passwordGenerator,
private ConfigurationManager $configurationManager,
) {
PasswordGenerator $passwordGenerator,
ConfigurationManager $configurationManager) {
$this->passwordGenerator = $passwordGenerator;
$this->configurationManager = $configurationManager;
}
public function Setup() : string {

View File

@@ -3,24 +3,44 @@
namespace AIO\Docker;
use AIO\Container\Container;
use AIO\Container\VersionState;
use AIO\Container\ContainerState;
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;
use AIO\Data\ConfigurationManager;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use AIO\ContainerDefinitionFetcher;
use http\Env\Response;
readonly class DockerActionManager {
class DockerActionManager
{
private const string API_VERSION = 'v1.41';
private Client $guzzleClient;
private \GuzzleHttp\Client $guzzleClient;
private ConfigurationManager $configurationManager;
private ContainerDefinitionFetcher $containerDefinitionFetcher;
private DockerHubManager $dockerHubManager;
public function __construct(
private ConfigurationManager $configurationManager,
private ContainerDefinitionFetcher $containerDefinitionFetcher,
private DockerHubManager $dockerHubManager
ConfigurationManager $configurationManager,
ContainerDefinitionFetcher $containerDefinitionFetcher,
DockerHubManager $dockerHubManager
) {
$this->guzzleClient = new Client(['curl' => [CURLOPT_UNIX_SOCKET_PATH => '/var/run/docker.sock']]);
$this->configurationManager = $configurationManager;
$this->containerDefinitionFetcher = $containerDefinitionFetcher;
$this->dockerHubManager = $dockerHubManager;
$this->guzzleClient = new \GuzzleHttp\Client(
[
'curl' => [
CURLOPT_UNIX_SOCKET_PATH => '/var/run/docker.sock',
],
]
);
}
private function BuildApiUrl(string $url) : string {
@@ -35,14 +55,14 @@ readonly class DockerActionManager {
return $container->GetContainerName() . ':' . $tag;
}
public function GetContainerRunningState(Container $container) : ContainerState
public function GetContainerRunningState(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 ContainerState::ImageDoesNotExist;
return new ImageDoesNotExistState();
}
throw $e;
}
@@ -50,20 +70,20 @@ readonly class DockerActionManager {
$responseBody = json_decode((string)$response->getBody(), true);
if ($responseBody['State']['Running'] === true) {
return ContainerState::Running;
return new RunningState();
} else {
return ContainerState::Stopped;
return new StoppedState();
}
}
public function GetContainerRestartingState(Container $container) : ContainerState
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 ContainerState::ImageDoesNotExist;
return new ImageDoesNotExistState();
}
throw $e;
}
@@ -71,13 +91,13 @@ readonly class DockerActionManager {
$responseBody = json_decode((string)$response->getBody(), true);
if ($responseBody['State']['Restarting'] === true) {
return ContainerState::Restarting;
return new RestartingState();
} else {
return ContainerState::NotRestarting;
return new NotRestartingState();
}
}
public function GetContainerUpdateState(Container $container) : VersionState
public function GetContainerUpdateState(Container $container) : IContainerState
{
$tag = $container->GetImageTag();
if ($tag === '%AIO_CHANNEL%') {
@@ -86,26 +106,28 @@ readonly class DockerActionManager {
$runningDigests = $this->GetRepoDigestsOfContainer($container->GetIdentifier());
if ($runningDigests === null) {
return VersionState::Different;
return new VersionDifferentState();
}
$remoteDigest = $this->dockerHubManager->GetLatestDigestOfTag($container->GetContainerName(), $tag);
if ($remoteDigest === null) {
return VersionState::Equal;
return new VersionEqualstate();
}
foreach($runningDigests as $runningDigest) {
if ($runningDigest === $remoteDigest) {
return VersionState::Equal;
return new VersionEqualState();
}
}
return VersionState::Different;
return new VersionDifferentState();
}
public function GetContainerStartingState(Container $container) : ContainerState
public function GetContainerStartingState(Container $container) : IContainerState
{
$runningState = $this->GetContainerRunningState($container);
if ($runningState === ContainerState::Stopped || $runningState === ContainerState::ImageDoesNotExist) {
return $runningState;
if ($runningState instanceof StoppedState) {
return new StoppedState();
} elseif ($runningState instanceof ImageDoesNotExistState) {
return new ImageDoesNotExistState();
}
$containerName = $container->GetIdentifier();
@@ -120,12 +142,12 @@ readonly class DockerActionManager {
$connection = @fsockopen($containerName, (int)$internalPort, $errno, $errstr, 0.2);
if ($connection) {
fclose($connection);
return ContainerState::Running;
return new RunningState();
} else {
return ContainerState::Starting;
return new StartingState();
}
} else {
return ContainerState::Running;
return new RunningState();
}
}
@@ -619,7 +641,7 @@ readonly class DockerActionManager {
$container = $this->containerDefinitionFetcher->GetContainerById($id);
$updateAvailable = "";
if ($container->GetUpdateState() === VersionState::Different) {
if ($container->GetUpdateState() instanceof VersionDifferentState) {
$updateAvailable = '1';
}
foreach ($container->GetDependsOn() as $dependency) {
@@ -780,7 +802,7 @@ readonly class DockerActionManager {
public function sendNotification(Container $container, string $subject, string $message, string $file = '/notify.sh') : void
{
if ($this->GetContainerStartingState($container) === ContainerState::Running) {
if ($this->GetContainerStartingState($container) instanceof RunningState) {
$containerName = $container->GetIdentifier();
@@ -964,7 +986,7 @@ readonly class DockerActionManager {
public function isLoginAllowed() : bool {
$id = 'nextcloud-aio-apache';
$apacheContainer = $this->containerDefinitionFetcher->GetContainerById($id);
if ($this->GetContainerStartingState($apacheContainer) === ContainerState::Running) {
if ($this->GetContainerStartingState($apacheContainer) instanceof RunningState) {
return false;
}
return true;
@@ -973,7 +995,7 @@ readonly class DockerActionManager {
public function isBackupContainerRunning() : bool {
$id = 'nextcloud-aio-borgbackup';
$backupContainer = $this->containerDefinitionFetcher->GetContainerById($id);
if ($this->GetContainerRunningState($backupContainer) === ContainerState::Running) {
if ($this->GetContainerRunningState($backupContainer) instanceof RunningState) {
return true;
}
return false;

View File

@@ -6,11 +6,12 @@ use AIO\ContainerDefinitionFetcher;
use AIO\Data\ConfigurationManager;
use GuzzleHttp\Client;
readonly class DockerHubManager {
class DockerHubManager
{
private Client $guzzleClient;
public function __construct(
) {
public function __construct()
{
$this->guzzleClient = new Client();
}
@@ -58,4 +59,4 @@ readonly class DockerHubManager {
return null;
}
}
}
}

View File

@@ -8,10 +8,12 @@ use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
readonly class AuthMiddleware {
public function __construct(
private AuthManager $authManager
) {
class AuthMiddleware
{
private AuthManager $authManager;
public function __construct(AuthManager $authManager) {
$this->authManager = $authManager;
}
public function __invoke(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface

View File

@@ -3,13 +3,17 @@
namespace AIO\Twig;
use Slim\Csrf\Guard;
use Twig\Extension\AbstractExtension;
use Twig\Extension\GlobalsInterface;
class CsrfExtension extends AbstractExtension implements GlobalsInterface {
public function __construct(
protected Guard $csrf
) {
class CsrfExtension extends \Twig\Extension\AbstractExtension implements \Twig\Extension\GlobalsInterface
{
/**
* @var Guard
*/
protected Guard $csrf;
public function __construct(Guard $csrf)
{
$this->csrf = $csrf;
}
public function getGlobals() : array
@@ -31,4 +35,4 @@ class CsrfExtension extends AbstractExtension implements GlobalsInterface {
]
];
}
}
}

View File

@@ -16,7 +16,7 @@
</header>
<main>
<h1>Nextcloud AIO v9.7.0</h1>
<h1>Nextcloud AIO v9.6.0</h1>
{# Add 2nd tab warning #}
<script type="text/javascript" src="second-tab-warning.js"></script>
@@ -40,19 +40,19 @@
{% endif %}
{% for container in containers %}
{% if container.GetDisplayName() != '' and container.GetRunningState().value == 'running' %}
{% if container.GetDisplayName() != '' and class(container.GetRunningState()) == 'AIO\\Container\\State\\RunningState' %}
{% set isAnyRunning = true %}
{% endif %}
{% if container.GetDisplayName() != '' and container.GetRestartingState().value == 'restarting' %}
{% if container.GetDisplayName() != '' and class(container.GetRestartingState()) == 'AIO\\Container\\State\\RestartingState' %}
{% set isAnyRestarting = true %}
{% endif %}
{% if container.GetIdentifier() == 'nextcloud-aio-watchtower' and container.GetRunningState().value == 'running' %}
{% if container.GetIdentifier() == 'nextcloud-aio-watchtower' and class(container.GetRunningState()) == 'AIO\\Container\\State\\RunningState' %}
{% set isWatchtowerRunning = true %}
{% endif %}
{% if container.GetIdentifier() == 'nextcloud-aio-domaincheck' and container.GetRunningState().value == 'running' %}
{% if container.GetIdentifier() == 'nextcloud-aio-domaincheck' and class(container.GetRunningState()) == 'AIO\\Container\\State\\RunningState' %}
{% set isDomaincheckRunning = true %}
{% endif %}
{% if container.GetIdentifier() == 'nextcloud-aio-apache' and container.GetStartingState().value == 'starting' %}
{% if container.GetIdentifier() == 'nextcloud-aio-apache' and class(container.GetStartingState()) == 'AIO\\Container\\State\\StartingState' %}
{% set isApacheStarting = true %}
{% endif %}
{% endfor %}
@@ -261,14 +261,14 @@
{% for container in containers %}
{% if container.GetDisplayName() != '' %}
<li>
{% if container.GetStartingState().value == 'starting' %}
{% if class(container.GetStartingState()) == 'AIO\\Container\\State\\StartingState' %}
<span class="status running"></span>
<span>{{ container.GetDisplayName() }} (<a href="/api/docker/logs?id={{ container.GetIdentifier() }}" target="_blank" rel="noopener">Starting</a>)
{% if container.GetDocumentation() != '' %}
(<a href="{{ container.GetDocumentation() }}">docs</a>)
{% endif %}
</span>
{% elseif container.GetRunningState().value == 'running' %}
{% elseif class(container.GetRunningState()) == 'AIO\\Container\\State\\RunningState' %}
<span class="status success"></span>
<span>{{ container.GetDisplayName() }} (<a href="/api/docker/logs?id={{ container.GetIdentifier() }}" target="_blank" rel="noopener">Running</a>)
{% if container.GetDocumentation() != '' %}

View File

@@ -353,9 +353,10 @@ server {
proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Accept-Encoding "";
proxy_set_header Host $host;
proxy_request_buffering off;
client_body_buffer_size 512k;
proxy_read_timeout 86400s;
client_max_body_size 0;