Skip to content

feat(nextcloud): package Nextcloud for RHEL 10 - #67

Open
markuslf wants to merge 2 commits into
mainfrom
feat/nextcloud
Open

markuslf wants to merge 2 commits into
mainfrom
feat/nextcloud

Conversation

@markuslf

Copy link
Copy Markdown
Member

Nextcloud server as RPM for RHEL 10, so that LFOps can update Nextcloud and its apps unattended through the package manager instead of the web updater. First version: 35.0.2. Other distributions follow once this layout has proven itself.

Changes

  • packages/nextcloud/: the spec follows the Fedora/EPEL package (nextcloud plus -httpd, -mysql, -postgresql, -sqlite; no -nginx), the layout follows the official Docker images: everything below /var/www/html/nextcloud, shipped apps read-only in apps/, app store apps in custom_apps/ (apps_paths in config/package.config.php). Unlike the images, the code belongs to root; apache can only write config/, custom_apps/, data/ and .htaccess. A CIL module labels these paths, the base policy does not know custom_apps/.
  • The tarball stays unpatched, so occ integrity:check-core passes; only updater/ and config/CAN_INSTALL are left out, occ becomes 0755.
  • %pre refuses a downgrade and a skipped major release, turns on maintenance mode, and takes over an installation the package did not install (LFOps role, tarball by hand): app store apps move to custom_apps/, the rest of the previous code to /var/www/html/.nextcloud-before-package-<timestamp>/ (0700). config/, data/, themes/ and a data directory inside the tree stay.
  • %posttrans runs /usr/libexec/nextcloud/post-update: maintenance mode off, occ upgrade when needed, db:add-missing-*, try-restart php-fpm. Without an installed instance it creates CAN_INSTALL. If it fails, dnf still succeeds; the instance stays on the update page until the script is run by hand.
  • Web updater off (upgrade.disable-web). nextcloud-jobs.timer is shipped, not enabled.
  • Dependencies: only the PHP extensions the admin manual lists as required, as capabilities that RHEL's PHP and Remi's meet alike; PHP pinned to the newest the distribution ships (8.4 on RHEL 10). nextcloud-httpd pulls in httpd and php-fpm and ships the vHost as an example in /usr/share/doc, nothing active. The subpackages require nextcloud without a version, so a refused downgrade cannot leave broken dependencies.
  • The build verifies the tarball against the Nextcloud Security key (28806A878AE423A28372792ED75899B9A724937A, as in the official Docker images): optional PKG_SOURCE_SIGNATURE_URL in package.conf, %{gpgverify} in %prep.
  • check-upstream.sh: optional PKG_UPSTREAM_MAJOR_MIN_PATCH (tags only). Nextcloud sets 1: a new major release is taken from its first bugfix release on, bugfix releases of the packaged major still come through.

Tests

On Rocky 10.2 VMs, SELinux enforcing:

  • Payload byte for byte identical to the 35.0.2 tarball (28148 files).
  • LFOps install (35.0.1, Remi PHP 8.5, store apps) + package 35.0.2: taken over, store apps in custom_apps/, occ upgrade ran, integrity check and rpm -V clean, 0 AVCs, new app store installs land in custom_apps/. A second LFOps run breaks nothing (it chowns the tree to apache again, to be removed in the role).
  • Fresh install from the package (35.0.1) with the example vHost, then package 35.0.2: occ upgrade ran, setup checks clean apart from HSTS, MariaDB tuning, maintenance window and mimetype migration. Downgrade to 35.0.1 refused by %pre, instance unchanged; the next update set the subpackages right again.
  • Manual install per the Nextcloud admin manual (34.0.5, AppStream PHP 8.3, AllowOverride All) + package 35.0.2: takeover with major upgrade, HTTP behaviour unchanged, .htaccess rewritten by occ upgrade. With the PHP 8.4 pin the package update on such a host is refused until it switches to php8.4-* with its extensions; after that and systemctl enable --now php-fpm.service (removing the old php-fpm disables it) the instance runs again. --allowerasing alone would drop APCu and Redis without replacement.
  • A tampered tarball fails %{gpgverify}.
  • check-upstream.sh against the tags of nextcloud/server and with synthetic tag lists (36.0.0 held back, 35.0.3 and 36.0.1 taken).

Laid out like the official Docker images below /var/www/html/nextcloud:
shipped apps read-only in apps/, app store apps in custom_apps/ via
apps_paths. Unlike the images, the code belongs to root; apache can only
write config/, custom_apps/, data/ and .htaccess, covered by a CIL module
for the SELinux contexts. The tarball stays unpatched, so
occ integrity:check-core passes (payload verified byte for byte against
the 35.0.2 tarball).

%pre refuses downgrades and skipped majors, turns on maintenance mode and
takes over an installation not installed by the package: app store apps
move to custom_apps/, the previous code to
/var/www/html/.nextcloud-before-package-*. %posttrans runs
/usr/libexec/nextcloud/post-update (occ upgrade, db:add-missing-*). The
web updater is off. PHP is pinned to the newest the distribution ships
(8.4 on RHEL 10). nextcloud-httpd only pulls in httpd and php-fpm and
ships the vHost as an example.

The build verifies the tarball against the Nextcloud Security key
(28806A878AE423A28372792ED75899B9A724937A) through the optional
PKG_SOURCE_SIGNATURE_URL in package.conf.

Verified on Rocky 10.2 VMs: takeover of an LFOps install (35.0.1 ->
35.0.2), fresh install plus package update (35.0.1 -> 35.0.2), and
takeover of a manual install per the Nextcloud admin manual
(34.0.5 -> 35.0.2).
Hosts update Nextcloud unattended, and occ upgrade disables the apps that
do not support a new major release yet. Hold a new major back until its
first bugfix release, as Nextcloud's own stable channel does.

check-upstream.sh gets PKG_UPSTREAM_MAJOR_MIN_PATCH for that. It only
works with tags: the latest GitHub release only shows the newest major,
while Nextcloud keeps publishing bugfix releases of the previous one, so
Nextcloud switches to PKG_UPSTREAM_SOURCE='tags'. The combination with
'releases' fails instead of silently doing nothing.

Tested against the tags of nextcloud/server (35.0.2 is current, 34.0.5
would bump to 35.0.2) and with synthetic tag lists (36.0.0 held back,
35.0.3 and 36.0.1 taken).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant