phar-io / phive

The Phar Installation and Verification Environment (PHIVE)
https://phar.io
BSD 3-Clause "New" or "Revised" License
571 stars 44 forks source link

"phive install" fails with exit code "1" and no error message (in GitLab CI) #423

Closed JanWennrichPCSG closed 3 months ago

JanWennrichPCSG commented 3 months ago

Hello,

I'm trying to use PHIVE to install my project tooling in GitLab CI.
After having trouble with file permissions (see #421), I have a different problem now:

I want to install all tools listed in my .phive/phars.xml in GitLab CI.
To do so, I'm using the following command:

yes | phive --no-progress --home ${CI_PROJECT_DIR}/.phive-home install --temporary

Everything seems to be working fine, until:

Import this key? [y|N] Linking /builds/quiqqer/test/.phive-home/phars/phpstan-1.10.60.phar to /builds/quiqqer/test/tools/phpstan

After that the pipeline stops with the following message:

ERROR: Job failed: exit code 1

See: https://dev.quiqqer.com/quiqqer/test/-/jobs/7173 (line 87 and 95)


When ignoring the return code, by using || true, the PHAR file is correctly symlinked in the tools/ folder.
See: https://dev.quiqqer.com/quiqqer/test/-/jobs/7172#L92 (line 92)

So something has to go wrong after creating the symlink (?)

The strange thing is that the exit code is zero, when executing the same command manually in the same Docker image as the pipeline uses. But I'm also not running into permission errors there, so it might be permission related again (? see #421)


Do you have any idea why this happens?
I suspect that it's related to piping yes into phive install.
In another project I'm already using the same command as mentioned above, but without piping yes and with explicitly stating the trusted GPG keys.

But unfortunately I cannot list all GPG keys in this pipeline, as I do not know what is listed in the phars.xml.
Is there another way to install everything from the phars.xml, without validating the GPG keys?


Or is there a way to install just one of the packages and it's version listed in the phars.xml?
For example with the following phars.xml:

<phive xmlns="https://phar.io/phive">
  <phar name="phpunit" version="^10.5.5" installed="10.5.5" location="./tools/phpunit" copy="false"/>
  <phar name="phpstan" version="1.10.60" installed="1.10.60" location="./tools/phpstan" copy="false"/>
  <phar name="composer-require-checker" version="^4.8.0" installed="4.8.0" location="./tools/composer-require-checker" copy="false"/>
</phive>

I just need to install phpstan in version 1.10.60 in my pipeline.
As a workaround I tried using phive --no-progress --home .phive-home update phpstan which installs just phpstan.
But as update does not have the --trust-gpg-keys option, the GPG key still has to be confirmed.
And as the --temporary flag does not exist, I'm getting permission errors again (see #421).
So unfortunately I can't use this approach.


Sorry for the long ticket and have a happy easter (holiday)!

JanWennrichPCSG commented 3 months ago

The strange thing is that the exit code is zero, when executing the same command manually in the same Docker image as the pipeline uses. But I'm also not running into permission errors there, so it might be permission related again (? see https://github.com/phar-io/phive/issues/421)

I just tried using sudo phive install and the problem still occurs: https://dev.quiqqer.com/quiqqer/test/-/jobs/7174 (see lines 74 and 95).
So it's probably not a permission problem

JanWennrichPCSG commented 3 months ago

The exit code "1" is probably not caused by PHIVE but by using "yes" and GitLab CI setting set -o pipefail

When yes tries to write to stdout but the program whose stdin that stdout is connected to is not reading, this will cause an EPIPE signal

See https://stackoverflow.com/a/49433335/3002417

I will verify and report back later, whether this is really causing the problem

theseer commented 3 months ago

I want to install all tools listed in my .phive/phars.xml in GitLab CI. To do so, I'm using the following command:

yes | phive --no-progress --home ${CI_PROJECT_DIR}/.phive-home install --temporary

I have to admit I never considered using yes for this. It feels a bit odd as that basically skips all security implied with validating the signatures.

Everything seems to be working fine, until:

Import this key? [y|N] Linking /builds/quiqqer/test/.phive-home/phars/phpstan-1.10.60.phar to /builds/quiqqer/test/tools/phpstan

After that the pipeline stops with the following message:

ERROR: Job failed: exit code 1

This cannot come from phive. We Do not use exit code 1 (see https://github.com/phar-io/phive/blob/master/src/shared/cli/Runner.php#L40 for reference).

See: https://dev.quiqqer.com/quiqqer/test/-/jobs/7173 (line 87 and 95)

When ignoring the return code, by using || true, the PHAR file is correctly symlinked in the tools/ folder. See: https://dev.quiqqer.com/quiqqer/test/-/jobs/7172#L92 (line 92)

So something has to go wrong after creating the symlink (?)

You already kind of answered that yourself with the later comment below. Besides: The symlink did work, otherwise the tool execution later wouldn't have worked.

But unfortunately I cannot list all GPG keys in this pipeline, as I do not know what is listed in the phars.xml.

I'd consider that a security problem. Because you're basically telling me you do not know what you'll be running in your pipeline. I can barely believe that.

Is there another way to install everything from the phars.xml, without validating the GPG keys?

No. This is the very point of phive and I'm still reluctant to implement such a switch.

[...] I just need to install phpstan in version 1.10.60 in my pipeline. As a workaround I tried using phive --no-progress --home .phive-home update phpstan which installs just phpstan.

That would also potentially upgrade phpstan to a newer version compatible with the version constraint used before. Not sure that's what you'd want in this context.

But as update does not have the --trust-gpg-keys option, the GPG key still has to be confirmed.

That's intentional, as the idea of an "update" is that it has previously been installed and thus the GPG key already is known. I know that this assumption falls short when the GPG sign key changed. Not sure if this needs to or should be changed.

And as the --temporary flag does not exist, I'm getting permission errors again (see #421). So unfortunately I can't use this approach.

That's actually worth adding. I'll open an issue for that later.

Sorry for the long ticket and have a happy easter (holiday)!

No worries.

A better solution than trying to mess with phive for your setup probably would be to independently from phive manage the gpg key chain:

If you add the $phive_home/gpg-directory to the cache, you could skip the import step and only do so whenever you add or replace a key. Not sure though if that saves you much time ;)

theseer commented 3 months ago

I closed this issue as I do not consider this a bug in phive given the subject.

For what it's worth: I'm planning to add a means to import gpg keys from local files using phive so one does not have to deal with gpg explicitly.