Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
strategy:
fail-fast: false
matrix:
php: [ 7.4, 8.0 ]
php: [ 7.4, 8.0, 8.2 ]
steps:
- name: Checkout code
uses: actions/checkout@v2
Expand Down
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 20260624
## What's Changed
* master office: prepare doil to deploy an OnlyOffice run-document-server
* add 2 apply states to en/disable office support for a specific ilias instance

## 20260611
## What's Changed
* update_hook.php - ensure that ilias >= 10 always has the update_hook file in public folder; works for CaT and Essential
Expand Down Expand Up @@ -31,6 +36,33 @@
* use node/npm versions depending on ilias version
* use new salt.sources while creating/importing instances

## 20260323
Comment thread
tbongers-cat marked this conversation as resolved.
## What's Changed
* master ilias-update-hook: adjust COMPOSER_HOME to point at correct location by @daniwe4 in https://github.com/conceptsandtraining/doil/pull/562
* master add update file for release 20260323 by @daniwe4 in https://github.com/conceptsandtraining/doil/pull/563

## 20260319
## What's Changed
* master 555: enable ILIAS https depending on doil https_proxy property by @daniwe4 in https://github.com/conceptsandtraining/doil/pull/558

## 20260318
## What's Changed
* master ilias cron: add path to cron starting script depending on ilias version by @daniwe4 in https://github.com/conceptsandtraining/doil/pull/557

## 20260224
## What's Changed
* master quick_fix: fix last release by @daniwe4 in https://github.com/conceptsandtraining/doil/pull/552

## 20260223
## What's Changed
* master SetIdpV10: new initialisation routine by @daniwe4 in https://github.com/conceptsandtraining/doil/pull/551

## 20251125
## What's Changed
* Master hotfix 20251125 by @daniwe4 in https://github.com/conceptsandtraining/doil/pull/543
* use node/npm versions depending on ilias version
* use new salt.sources while creating/importing instances

## 20251103
## What's Changed
* update Captainhook Hooks while running update_hook script
Expand Down
29 changes: 28 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ all mails from your instances, so you can test the ILIAS emailing.
1. adjust your mail password in `setup/conf/doil.conf`
1. if you run global instances make sure to adjust 'global_instances_path' in `setup/conf/doil.conf` to specify
where to place them, default is '/srv/instances'. Attention, paths with 'home' are not allowed here.
1. if you want to enable office support ensure to set enable_office to true in `setup/conf/doil.conf`
1. execute `sudo ./setup/install.sh` in order to install **doil**
1. you can remove the downloaded folder afterwards
1. check `doil help` for available commands and further instructions
Expand Down Expand Up @@ -56,7 +57,7 @@ however **doil** needs [Docker](https://www.docker.com/) in order to work:
* git
* .ssh folder in your home directory. **doil** will mount it into the container. **doil** needs this to have access to any private git repositories that may be used.

Additional dependencies, but these are installed automatically during setup.
Additional dependencies, but these are installed automatically during setup and only inside containers.

* php version => 7.4
* php*.*-zip
Expand All @@ -72,6 +73,12 @@ Additional dependencies, but these are installed automatically during setup.
* psr/log
* monolog/monolog

if office is enabled, these dependencies will also be installed

* onlyoffice/documentserver
* postgres
* rabbitmq

The easiest way to fulfill the dependencies is Ubuntu 22.01, but it should also be possible with any other Linux installation.

## Usage
Expand Down Expand Up @@ -436,6 +443,26 @@ users, so make sure to understand what you are doing.

See `doil keycloak:<command> --help` for more information


### Office Sever

If enabled **doil** installs an OnlyOffice server. This enables ILIAS to
support document editing in office style.

* `doil office:down` stops the office server
* `doil office:login` logs the user into the office server
* `doil office:restart` restarts the office server
* `doil office:up` starts the office server

See `doil office:<command> --help` for more information

To enable or disable Office support for a specific ILIAS instance, there
are two states that can be selected using `doil apply <instancename>`.
These are `enable-office` and `disable-office`.

When a new instance is installed, you are asked during the installation
process whether Office should be activated for this instance.

### xdedug

**doil** provides two options to enable xdebug for the given instance.
Expand Down
2 changes: 1 addition & 1 deletion app/src/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class App extends Application
{
const NAME = "Doil Version 20260617 - build 2026-06-17";
const NAME = "Doil Version 20260624 - build 2026-06-24";

public function __construct(Command ...$commands)
{
Expand Down
24 changes: 22 additions & 2 deletions app/src/Commands/Instances/CreateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,14 @@ public function configure() : void
->addOption("xdebug", "x", InputOption::VALUE_NONE, "Determines if xdebug should be installed or not")
->addOption("global", "g", InputOption::VALUE_NONE, "Determines if an instance is global or not")
->addOption("skip-readme", "s", InputOption::VALUE_NONE, "Doesn't create the README.md file")
->addOption("enable-office", "o", InputOption::VALUE_NONE, "Enable office support")
;
}

public function execute(InputInterface $input, OutputInterface $output) : int
{
$options = $this->gatherOptionData($input, $output);
$doil_conf = $this->filesystem->parseIniFile(self::DOIL_INI_PATH);
$options = $this->gatherOptionData($input, $output, $doil_conf);

$host = $doil_conf["host"];
$allowed_hosts = $doil_conf["allowed_hosts"];
Expand Down Expand Up @@ -492,6 +493,13 @@ public function execute(InputInterface $input, OutputInterface $output) : int
$this->writer->endBlock();
}

if ($options['enable_office']) {
// apply enable-office state
$this->writer->beginBlock($output, "Apply enable-office state");
$this->docker->applyState($instance_salt_name, "enable-office");
$this->writer->endBlock();
}

// apply access state
$this->writer->beginBlock($output, "Apply access state");
$this->docker->applyState($instance_salt_name, "access");
Expand Down Expand Up @@ -574,7 +582,7 @@ public function execute(InputInterface $input, OutputInterface $output) : int
return Command::SUCCESS;
}

protected function gatherOptionData(InputInterface $input, OutputInterface $output) : array
protected function gatherOptionData(InputInterface $input, OutputInterface $output, array $doil_conf) : array
{
$options = [];

Expand All @@ -587,6 +595,7 @@ protected function gatherOptionData(InputInterface $input, OutputInterface $outp
$xdebug = $input->getOption("xdebug");
$global = $input->getOption("global");
$skip_readme = $input->getOption("skip-readme");
$enable_office = $input->getOption("enable-office");

$one_option_missed = is_null($name) || is_null($repo) || is_null($branch) || is_null($php_version) || is_null($target);

Expand Down Expand Up @@ -738,6 +747,17 @@ protected function gatherOptionData(InputInterface $input, OutputInterface $outp
}
$options["skip_readme"] = $skip_readme;

// Enable office support
if (!$enable_office && $one_option_missed && $doil_conf['enable_office']) {
$question = new ConfirmationQuestion(
"Enable office support? [yN]: ",
false
);
$enable_office = $helper->ask($input, $output, $question);
}
$options["enable_office"] = $enable_office;


// Target
if (is_null($target) && !$global) {
$question = new Question("Please enter a target where doil should install " . $options["name"] . ". Leave blank for current directory. : ");
Expand Down
3 changes: 3 additions & 0 deletions app/src/Commands/Instances/StatusCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ public function execute(InputInterface $input, OutputInterface $output) : int
strstr($a, "doil_proxy") ||
strstr($a, "doil_saltmain") ||
strstr($a, "doil_keycloak") ||
strstr($a, "doil_office") ||
strstr($a, "doil_postgresql") ||
strstr($a, "doil_rabbitmq") ||
strstr($a, "_local") ||
strstr($a, "_global")
) {
Expand Down
45 changes: 45 additions & 0 deletions app/src/Commands/Office/DownCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php declare(strict_types=1);

/* Copyright (c) 2026 - Daniel Weise <daniel.weise@concepts-and-training.de> - Extended GPL, see LICENSE */

namespace CaT\Doil\Commands\Office;

use CaT\Doil\Lib\Docker\Docker;
use CaT\Doil\Lib\ConsoleOutput\Writer;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class DownCommand extends Command
{
protected const OFFICE_PATH = "/usr/local/lib/doil/server/office";

protected static $defaultName = "office:down";
protected static $defaultDescription = "Stops the office server";

protected Docker $docker;
protected Writer $writer;

public function __construct(Docker $docker, Writer $writer)
{
parent::__construct();

$this->docker = $docker;
$this->writer = $writer;
}


public function execute(InputInterface $input, OutputInterface $output) : int
{
if (! $this->docker->isInstanceUp(self::OFFICE_PATH)) {
$output->writeln("Nothing to do. Office is already down.");
return Command::SUCCESS;
}

$this->writer->beginBlock($output, "Stop office");
$this->docker->stopContainerByDockerCompose(self::OFFICE_PATH);
$this->writer->endBlock();

return Command::SUCCESS;
}
}
38 changes: 38 additions & 0 deletions app/src/Commands/Office/LoginCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php declare(strict_types=1);

/* Copyright (c) 2026 - Daniel Weise <daniel.weise@concepts-and-training.de> - Extended GPL, see LICENSE */

namespace CaT\Doil\Commands\Office;

use CaT\Doil\Lib\Docker\Docker;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class LoginCommand extends Command
{
protected const OFFICE_PATH = "/usr/local/lib/doil/server/office";

protected static $defaultName = "office:login";
protected static $defaultDescription = "Login into the office server";

protected Docker $docker;

public function __construct(Docker $docker)
{
parent::__construct();

$this->docker = $docker;
}


public function execute(InputInterface $input, OutputInterface $output) : int
{
if (! $this->docker->isInstanceUp(self::OFFICE_PATH)) {
$this->docker->startContainerByDockerCompose(self::OFFICE_PATH);
}

$this->docker->loginIntoContainer(self::OFFICE_PATH, "doil_office");
return Command::SUCCESS;
}
}
66 changes: 66 additions & 0 deletions app/src/Commands/Office/RestartCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php declare(strict_types=1);

/* Copyright (c) 2026 - Daniel Weise <daniel.weise@concepts-and-training.de> - Extended GPL, see LICENSE */

namespace CaT\Doil\Commands\Office;

use CaT\Doil\Lib\Docker\Docker;
use CaT\Doil\Lib\ConsoleOutput\Writer;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class RestartCommand extends Command
{
protected const OFFICE_PATH = "/usr/local/lib/doil/server/office";

protected static $defaultName = "office:restart";
protected static $defaultDescription = "Restarts the office server";

protected Docker $docker;
protected Writer $writer;

public function __construct(Docker $docker, Writer $writer)
{
parent::__construct();

$this->docker = $docker;
$this->writer = $writer;
}


public function execute(InputInterface $input, OutputInterface $output) : int
{
if (! $this->docker->isInstanceUp(self::OFFICE_PATH)) {
$this->docker->startContainerByDockerCompose(self::OFFICE_PATH);
return Command::SUCCESS;
}

$this->writer->beginBlock($output, "Restart office");
$this->docker->stopContainerByDockerCompose(self::OFFICE_PATH);
$this->docker->startContainerByDockerCompose(self::OFFICE_PATH);
sleep(3);
$instances = array_filter($this->docker->getRunningInstanceNames());
foreach ($instances as $instance) {
if ($instance == "doil_office") {
continue;
}
if (
strpos($instance, 'doil_') != false ||
strpos($instance, '_local') != false ||
strpos($instance, '_global') != false
) {
try {
$this->docker->executeDockerCommand(
$instance,
"supervisorctl start startup 2>&1 >/dev/null"
);
} catch (\Exception $e) {
}
}
}
$this->writer->endBlock();

return Command::SUCCESS;
}
}
Loading
Loading