deployer: Phar problems: crc32 mismatch on file
Iβm having some issues with deployer connections. When I try to php ./vendor/bin/dep ssh test
it fails 50% of the time. This is both on my local machine running Arch as well on my Gitlab server in CI/CD. Php version is 8.0.7 on Arch, 8.0.5 on the alpine based docker image used for CI/CD in Gitlab.
- Deployer version: 7.0.0-beta.23
- Deployment OS: ubuntu (docker container) / archlinux
In testing I have reduced my deploy.yaml to a minimal setup like this:
config:
application: APPNAME
user: USER
host: HOST
base_deploy_path: "~/domains"
repository: "REPONAME"
hosts:
test:
remote_user: "{{user}}"
hostname: "{{host}}"
deploy_path: "{{base_deploy_path}}/APPLICATION_URL"
This is what I get when the CD fails with this issue:
$ php ./vendor/bin/dep deploy test
In ClassLoader.php line 444:
include(phar:///builds/APPLICATION_NAME/vendor/deployer/dist/dep/vendor/com
poser/../../src/Selector/Selector.php): Failed to open stream: phar error:
internal corruption of phar "/builds/APPLICATION_NAME/vendor/deployer/dist/
dep" (crc32 mismatch on file "src/Selector/Selector.php")
deploy [--tag TAG] [--revision REVISION] [--branch BRANCH] [-o|--option OPTION] [-l|--limit LIMIT] [--no-hooks] [--plan] [--start-from START-FROM] [--log LOG] [--profile PROFILE] [--] [<selector>...]
The application server is running OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017. I could try to have that updated to a newer build as it seems a bit old to me.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 38 (14 by maintainers)
π π π π π π π π π π π π π π π π π π π π π π π π π π π π π
Released 7.0.0-beta.25. Please test it out! Should be fixed now!
Yes, thanks a lot. I already know how to fix it. Will write pr today and release it.
Just chiming in here because Iβve encountered and addressed similar problems for some client project with https://github.com/clue/phar-composer in the past and it looks like this could be related to inherited file descriptors in forked PHP processes. See https://github.com/reactphp/child-process/issues/51 and in particular the linked issues for all the gory details. (Yep, messing with these subtle, low-level details in PHP is what I happen to do for a living and actually spend a lot of time on.)
The gist: Forking is easy β except itβs not.
Whenever you spawn a child process or fork a process on Unix-based platforms, all child processes will inherit all open file descriptors by default. On Unix-based platforms, this can be controlled through the
FD_CLOEXEC
andO_CLOEXEC
flags (neither of which are exposed to PHP).In itself, this isnβt a big deal for many applications as child processes would usually disregard any inherited file descriptors and simply open new ones themselves. This is however a major problem when using
pcntl_fork()
and Phar archives in PHP: The forked process will have a reference to the open Phar archive and the same underlying file descriptor. This means that if either the parent or the child process reads from the Phar archive, it will advance the FD position without the other process being aware. This is why one of the processes may read garbled/invalid data and would report a CRC error in this case.This can be avoided by making sure each child process has a unique reference to the Phar archive, i.e. by using
exec()
(and family) instead ofpcntl_fork()
or not using Phar archives at all in combination withpcntl_fork()
. Additionally, you may be able to work around this issue by making sure all classes are loaded into memory before forking, as the child process would no longer have to seek in the Phar archive.I think https://stackoverflow.com/questions/29413013/phar-internal-corruption-crc32-mismatch-during-process-fork does a pretty good job at explaining whatβs going on here.
I hope this helps π
Tested using PHP 8.0 & PHP 7.4 on Github Actions (ubuntu-latest) and MacOS Big Sur (latest build): everything works perfectly. Tests on Windows build agents will follow next week, but I will keep silence unless any issue found.
Thank you @antonmedv for quick resolution of this nasty bug! Great tool!
The first attempt was successful. If someone can, check with yourself.
https://twitter.com/shyim97/status/1418271370421719041?s=21 I read something in phpunit that they require all classes before executing any code to avoid a bug. Maybe thatβs help here too?
Managed to reproduce the same issue down to at least r10, until the version differences got big enough that my deploy.php no longer worked.
I also attempted building the phar using build script from 6.x branch and code from r24, but still got the same errors (I donβt really know much about building phar archives, so perhaps I did something wrong / thereβs some internal cache somewhere / etc - so please take this with a grain of salt).
@Schrank A colleague suggested it could be a race condition in phar loading. Where the crc is checked while it is still loading or multiple processes are loading the phar at the same time and corrupting the unpacked files.
An important piece of information missing on this issue: Iβm using the deployer/dist package installed with composer.
Iβve tried with the source build βdeployer/deployerβ and lo and behold, everything works fine. So this issue seems to be only with the deployer/dist package. And it seems to be related to composer class loading. Iβve found something kind of related maybe: https://stackoverflow.com/questions/29413013/phar-internal-corruption-crc32-mismatch-during-process-fork