New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
touch(): Utime failed: Permission denied #4070
Comments
|
So we should just do a is_writable check before doing the touch? I am not sure however why this commit breaks it and why it wasn't an issue before? Is the filemtime() call failing? Because touch() by default changes both access and modification time as far as I can tell, which we still do. /cc @joshdifabio |
|
@abrudin I get the following error if I change ownership of a cached file and then run However, I see this error even when I revert 051b7bd. Have you already tried reverting that change yourself to see if it does indeed resolve the issue? Regardless, it might make sense only to invoke |
|
Yeah it strikes me as kind of impossible to share the cache dir in a
sensible way if all users don't have write access to it, because then
the cache can't be written to.
|
|
Well, every user has write access to the cache, the problem is that utime needs ownership of the file (or root access), which everybody obviously cannot have. We reverted to 1.0.0-alpha10 (from 1.0.0-dev) and then it started working again. Previously it failed on that exact line. So the problem is not write permissions, but ownership. So I guess it is the filemtime thing that invokes utime and thus fails if it is not owned by the current user. Something like if(get_current_user() == fileowner ( $filename )) {touch with filemtime} else {touch without filemtime} could probably work. |
|
I'm able to reproduce this error both on @abrudin I think I know why it worked for you after rolling back to alpha10: whenever Composer fails to copy a file from its cache directory it will attempt to delete that file from its cache. In the case of this error, the file with the wrong (or at least different) ownership is removed by Composer from its cache during the failed build. It is then downloaded afresh and re-created in the cache directory with the correct ownership on the following build, and so that build will succeed. Even if you build repeatedly with 051b7bd you should see successful builds. I've seen this myself when reproducing this issue. Just to be clear, Checking the file ownership prior to invoking |
|
@joshdifabio We have used this setup for several months, and yesterday after updating composer was the first time we ran into this issue. We can also see that building several times will eventually succeed (because of what you write above), but we have a lot of libraries so that would mean a lot of fails before we are through them all. We have tested back and forth so we are pretty sure the issue exists in the latest version but not in alpha10. That said, it does not necessary mean that it is that commit that makes it fail, I have yet not had time to bisect the exact commit, it only seemed reasonable as that was the line that failed and it was changed recently. I am going to try to pin down the issue more in detail and setup a test case, so that it will be clear exactly what the problem is. It could be noted that PHP:s touch implementation (https://github.com/php/php-src/blob/cf50748f2ba16cef1d2931c0d8afc717dea8eab7/ext/standard/filestat.c) behaves differently depending on the number of arguments, so I would not rule the mentioned commit out completely, but as you say it seems like the issue would have been the same before as you cannot use php:s touch without ownership (according to several comments in the docs). I'll be back with some more details. |
|
Maybe I should mention that we have this issue on Ubuntu 12.04, PHP 5.5.24. |
|
The touch operation cannot be the touch root cause of your issue, because as others have mentioned, it was already present (the only thing that was changed was the value of the modified time, not the action itself). It is more likely something else in your environment changed. Was updating composer literally the only step you took? Everything else in your build process was 100% guaranteed left untouched? |
|
On another note, there should be some more sanity checks probably to preclude scenarios such as these from breaking the flow. |
|
@alcohol: Yes updating composer was the only change. We downgraded then it worked, we upgraded again it stopped working, downgraded it worked. As I mentioned above the touch function works slightly different when invoking it with three arguments, depending on for example if HAVE_UTIME_NULL is defined on the system, and some paths only returns false without causing an error etc (https://github.com/php/php-src/blob/cf50748f2ba16cef1d2931c0d8afc717dea8eab7/ext/standard/filestat.c#LC701), but I agree that it doesn't look like it should have worked before the change in touch() either if you do not own the file. I hope I will get some time later today to investigate more thoroughly which commit that actually breaks it for us. |
|
Your claim that it behaves different based on number of arguments is simply not true in this scenario. There must be something else that modified the cache behaviour in composer between those two versions. The fact that Edit: to illustrate why the amount of arguments is not really relevant, this is the offending/failing part. |
|
Hello again, now I have done a git bisect to narrow down the commit that makes it fail, and it was indeed the previously mentioned commit: I also took that commit and manually edited the cache file (removed the two last arguments for touch) just to be 100% sure. I have created a test case and I will try to describe it as good as possible: Change the owner of the files created in the cache (but keep the group, to similate that another user did the composer install) and remove all the files in vendor: Run again. Before commit 051b7bd it works fine, after it fails with the utime error message. |
|
Can you verify that it actually touches it though? Does it run through the discussed block of code? |
|
This is interesting: http://linux.die.net/man/2/utime
It would seem the NULL does make a difference for the underlying implementation of |
|
@alcohol: Yes, I verified that it ran the line (and that the touch call returned true when invoked with only one parameter), so it seems your finding might be the issue. |
|
@alcohol @abrudin well done, guys! FYI you can prove this quite easily: # unix command line
$ touch delete.me
$ sudo chown another:user delete.me
$ touch delete.me # succeeds
$ touch delete.me -a # access time only: fails<?php
touch('delete.me'); // succeeds
touch('delete.me', null, time()); // failsI think we need to switch approaches based on the file owner. |
|
How about |
|
On the other hand, adding permission and owner checks is kind of elaborate for an issue this minor. |
|
Thanks for your help! I'll monitor this issue and upgrade as soon as it is fixed, but I'm convinced you will find the most appropriate solution given all possible different scenarios. If you want me to do anything more regarding this, just let me know. |
|
Ok I pushed a tentative fix, if you can confirm it works with the latest
phar that'd be great.
|
|
Assuming Composer's error handler respects if (fileowner(file) === posix_geteuid()) {
touch(file, ...)
} else {
touch(file)
} |
|
Yes, it works just fine. Thanks again for your help and impressing speed. |
|
I was having issues with this too, even after updating to the latest version. I figured there were some broken permissions in the cache so I re-installed from scratch and it's working fine now. |
|
@Seldaek not working. Still getting:
|
|
I actually get that error too sometimes. Although very sporadically. Usually if I retry it just works. Weird behaviour (OSX) :-/ |
|
I fixed it somehow on an Ubuntu VM yesterday, but another VM started today with the same behavior. But I didn't remember what I did do to fix it. |
|
@Jaspur do you get an exception or just that line in the output and it continues? If an exception please run with -v and paste the backtrace, just to be sure where it comes from. |
|
|
So that's a touch() on the vendor-dir to indicate that the dependencies changed.. Permission denied is definitely weird, but I guess I could suppress that one as if it doesn't work it's not critical to 99% of people. |
|
Thnx |
|
@Seldaek Got this on Ubuntu |
|
For me also, same error |
|
@pavankumarkatakam are you using the latest version of Composer? |
|
yes |
|
... while 'Installing zendframework/skeleton-application' (osx) [ErrorException]
touch(): Utime failed: Permission denied
Exception trace:
() at phar:///usr/local/bin/composer/src/Composer/Cache.php:151
Composer\Util\ErrorHandler::handle() at n/a:n/a
touch() at phar:///usr/local/bin/composer/src/Composer/Cache.php:151
Composer\Cache->copyTo() at phar:///usr/local/bin/composer/src/Composer/Downloader/FileDownloader.php:127
Composer\Downloader\FileDownloader->doDownload() at phar:///usr/local/bin/composer/src/Composer/Downloader/FileDownloader.php:88
Composer\Downloader\FileDownloader->download() at phar:///usr/local/bin/composer/src/Composer/Downloader/ArchiveDownloader.php:35
Composer\Downloader\ArchiveDownloader->download() at phar:///usr/local/bin/composer/src/Composer/Downloader/DownloadManager.php:199
Composer\Downloader\DownloadManager->download() at phar:///usr/local/bin/composer/src/Composer/Installer/LibraryInstaller.php:175
Composer\Installer\LibraryInstaller->installCode() at phar:///usr/local/bin/composer/src/Composer/Installer/LibraryInstaller.php:89
Composer\Installer\LibraryInstaller->install() at phar:///usr/local/bin/composer/src/Composer/Installer/InstallationManager.php:152
Composer\Installer\InstallationManager->install() at phar:///usr/local/bin/composer/src/Composer/Installer/InstallationManager.php:139
Composer\Installer\InstallationManager->execute() at phar:///usr/local/bin/composer/src/Composer/Installer.php:604
Composer\Installer->doInstall() at phar:///usr/local/bin/composer/src/Composer/Installer.php:232
Composer\Installer->run() at phar:///usr/local/bin/composer/src/Composer/Command/CreateProjectCommand.php:172
Composer\Command\CreateProjectCommand->installProject() at phar:///usr/local/bin/composer/src/Composer/Command/CreateProjectCommand.php:130
Composer\Command\CreateProjectCommand->execute() at phar:///usr/local/bin/composer/vendor/symfony/console/Command/Command.php:256
Symfony\Component\Console\Command\Command->run() at phar:///usr/local/bin/composer/vendor/symfony/console/Application.php:838
Symfony\Component\Console\Application->doRunCommand() at phar:///usr/local/bin/composer/vendor/symfony/console/Application.php:189
Symfony\Component\Console\Application->doRun() at phar:///usr/local/bin/composer/src/Composer/Console/Application.php:167
Composer\Console\Application->doRun() at phar:///usr/local/bin/composer/vendor/symfony/console/Application.php:120
Symfony\Component\Console\Application->run() at phar:///usr/local/bin/composer/src/Composer/Console/Application.php:98
Composer\Console\Application->run() at phar:///usr/local/bin/composer/bin/composer:43
require() at /usr/local/bin/composer:25 |
|
It seems that |
|
composer clearcache is not an option in some jenkins or other CI tools. Clearing cache and re-downloading all those packages again increase build time. |
|
It's quite probably a cache corruption. As far as I can see in the code however there is no real reason for it to be fatal - worst that could happen is that it gets cleaned up too soon. Pushing a PR in a sec. |
|
try running |
|
I tried composer clear-cache and that didn't fix the issue for me. Please help! |
|
Thank you very much, kala725. sudo composer clear-cache helped me at once ! ))) |
|
Same error, but change permissions, 'sudo composer clear-cache' or remove vendor dir and ''composer update' isn't help. Laravel v5.5.40 |
|
That's not a Composer error. |
After commit 051b7bd it is no longer possible to have a shared composer cache, as the user running composer has to own the file in order to run utime which is done by touch($this->root . $file, filemtime($this->root . $file), time());
It would be desirable to only try to run utime if the user owns the file.
The text was updated successfully, but these errors were encountered: