-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Symfony4 recipe - writable setfacl "Operation not permitted" at second deployment #2932
Description
- Deployer version: 6.8.0
- Deployment OS: Debian GNU/Linux 11 (bullseye)
I have the same problem as reported on closed issues #1976 and #2044 but where the problems seems to not have been understood. Maybe this issue will resolve the problem 🤞
I use the Symfony4 recipe to deploy my application and this recipe indicates that the default shared dirs are 'var/log', 'var/sessions' and the writable dir 'var'.
Here is my very simple deploy.php :
<?php
namespace Deployer;
require 'recipe/symfony4.php';
// Configuration
set('repository', 'git@XXX.git');
add('shared_dirs', ['public/uploads', 'public/media', 'public/pdf']);
add('writable_dirs', ['public/uploads', 'public/media', 'public/pdf']);
// Servers
host('preprod')
->hostname('XXX')
->user('deploy')
->set('branch', 'develop')
->set('deploy_path', '/var/www/XXX')
;If the first deployment was a success, I tried to deploy a new version of my code a few days later and I have now this issue :
[Deployer\Exception\RuntimeException (1)]
The command "cd /var/www/XXX/releases/2 && (setfacl -L -R -m u:"www-data":rwX -m u:`whoami`:rwX var)" failed.
Exit Code: 1 (General error)
Host Name: preprod
================
setfacl: var/log/prod-2022-01-28.log: Operation not permitted
...After some investigations, the problem is that the writable code for ACL checks first if the writable folder has ACL configuration for the web server user (here www-data). See recipe/deploy/writable.php#L115 :
// Check if ACL has been set or not
$hasfacl = run("getfacl -p $dir | grep \"^user:$httpUser:.*w\" | wc -l");
// Set ACL for directory if it has not been set before
if (!$hasfacl) {
run("setfacl -L $recursive $setFaclUsers $dir");
run("setfacl -dL $recursive $setFaclUsers $dir");
}Here the global directory 'var' is a fresh one from the git clone, so it hasn't ACL configuration, so the if statement make the code try to set ACL on it, but as the symlinked subfolders log or session contain files created by the webserver, the command fails.
As indicated by this documentation :
Requirement: To issue setfacl, you must be the file owner or have superuser authority
And as thedeployuser is neither the owner (herewww-data) neither a sudo, the setfacl command fails.
To avoid this issue, the solution is to update the recipe to specify the subfolders (like it was done is Symfony 3 recipe) :
- set('writable_dirs', ['var']);
+ set('writable_dirs', ['var/cache', 'var/log', 'var/sessions']);With this configuration, at the second deployment, the writable code is now able to check get the information that the 'var/log' and 'var/sessions' folders have already ACL configuration for the web server user, and avoid to call the setfacl function. It will only be called by default on the fresh new empty var/cache folder.