Skip to content
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

Project configuration file not loaded V2.1 #285

Open
eradin opened this issue Feb 21, 2020 · 21 comments
Open

Project configuration file not loaded V2.1 #285

eradin opened this issue Feb 21, 2020 · 21 comments
Milestone

Comments

@eradin
Copy link

eradin commented Feb 21, 2020

Hi, this was an issue with V1.7 but I am seeing something similar with 2.1.

Reference: #108

I have installed crunz and uploaded to my server. The test server is a shared hosted environment (linux) running php 7.2. I have set up cron per the instructions with a copy of the config file in my project root folder. When I run the command from cron with debugging level 3, I get an error

No task found! Please check your source path. Additional output show it can't find the config file in ..lavary/crunz.

When I run this same command from the cli, it works perfectly. Finding the config in the root along with the tasks in the tasks directory (also in the root).

I did a little testing and discovered the first script file bin/crunz shows the cwd as the project root but then changes the directory to call the second script in lavary/crunz. When I print the cwd from the second script it shows the cwd as ..lavary/crunz. When I run from the cli, both files cwd's are the project root.

Same scripts, same command. The cli method works as advertised but the cron method fails due to an erroneous current directory. Obviously the cron version is more important.

Is this a bug? I was able to patch it up by adding a symbolic link in the lavary/crunz directory to point to the config.yml in the root. Then I added the path to the task directory in the cron command line. This works but it's very kludgy (not to mention I had to make a lot of paths absolute in my task file).

Has anybody seen this before?

@PabloKowalczyk
Copy link
Collaborator

Hello,

in v2.1 Crunz will only look for crunz.yml in current working directory (https://github.com/lavary/crunz/blob/master/UPGRADE.md#upgrading-from-v110-to-v111).

Could you show me result of vendor/bin/crunz schedule:run -vvv and your Cron entry?

@eradin
Copy link
Author

eradin commented Feb 21, 2020

Thank you for the feedback. I am doing everything according to the docs. Here is some more information.

cron job:
cd /home/relevant/public_html && vendor/bin/crunz schedule:run -vvv > tasks.log 2>&1

directory structure
public_html/
-crunz.yml
-tasks/
-vendor/
--bin/
---crunz

Output of run:
Config file not found, exception message: 'Unable to find config file "/home/relevant/public_html/vendor/lavary/crunz/crunz.yml".'.
Unable to find/parse config file, fallback to default values.
Task source path '/home/relevant/public_html/vendor/lavary/crunz/tasks'
No task found! Please check your source path.
Content-type: text/html; charset=UTF-8

As you can see, it does change directory from the cron command but when it runs lavary/crunz, it thinks it's in that directory not the project root.

@davidsneighbour
Copy link
Contributor

davidsneighbour commented Feb 22, 2020

In my experience on shared hosting you should use the full path and call php, like the following:

cd /home/relevant/public_html && php ./vendor/bin/crunz schedule:run -vvv > tasks.log 2>&1

./vendor/bin/crunz might have to be even /home/relevant/public_html/vendor/bin/crunz

The following works for me in my crontab:

* * * * * cd /home/username/webroot && /usr/local/php73/bin/php vendor/bin/crunz schedule:run

@PabloKowalczyk
Copy link
Collaborator

@davidsneighbour good tip, using absolute path is always better option.

@eradin Here is output for command cd /var/www/html && vendor/bin/crunz s:l -vvv in my project (missing crunz.yml on purpose):

Unable to find/parse config file, fallback to default values.
Task source path '/var/www/html/tasks'
Task finder suffix: 'Tasks.php'
Realpath for '/var/www/html/tasks' is '/var/www/html/tasks'
Found 1 task(s) at path '/var/www/html/tasks'

Everything works as expected. Are you sure Crunz version (vendor/bin/crunz --version) on server is v2.1?

@eradin
Copy link
Author

eradin commented Feb 22, 2020

I just checked again. --version show V2.1.

I also tried absolute path:

cd /home/relevant/public_html && /home/relevant/public_html/vendor/bin/crunz schedule:run -vvv > tasks.log 2>&1

tasks.log:
Config file not found, exception message: 'Unable to find config file "/home/relevant/public_html/vendor/lavary/crunz/crunz.yml".'.
Unable to find/parse config file, fallback to default values.
Task source path '/home/relevant/public_html/vendor/lavary/crunz/tasks'
No task found! Please check your source path.
Content-type: text/html; charset=UTF-8

I will repeat, this is only a problem from cron. Running from shell works fine. It's also a shared hosting environment which could be significant.

Observation: In the bin/crunz file, the first line is
dir=$(cd "${0%[/\]*}" > /dev/null; cd "../lavary/crunz" && pwd)

Could that 2nd cd be causing the problem? If so, why would it work differently on cron vs the cli?

UPDATE
I replaced the lines in the bin/crunz file with an absolute path

/home/relevant/public_html/vendor/lavary/crunz/crunz "$@"

Oddly, the tasks.log file is unchanged. So who's changing the root directory?

@eradin
Copy link
Author

eradin commented Feb 22, 2020

A little more information. I added a pwd command in bin/crunz right before the call to the lavary/crunz script. It prints out the current working directory (.../public_html). I also added a line at the top of the lavary/crunz script echo getcwd(). It prints out .../public_html/vendor/lavary/crunz. This suggests cron is changing the directory when the script is run. I don't want to waste anymore of anybodies time if this is a server config problem but it starting to look that way.

@eradin
Copy link
Author

eradin commented Feb 23, 2020

Ok, I figured out the problem. I am documenting the reasons here in hope I save some poor sole some valuable time and frustration. It should also improve the out of the box experience for newbies. This is really a great tool and it should work right out of the box.

I ran several tests independent of crunz. Apparently, getcwd(), which crunz is using, returns different results based on the php interpreter being used. In my case, the CLI was using cli and cron was using cgi-fcgi. The cli version will return the working directory as set in the shell. Cron (and the web server) will return the path of the invoked script. Since my versions are different, I get different results. You can see what cron is using by running php -v > phpver.log as a cron job (run the same from the shell and compare).

Now, this means crunz won't work properly in all environments (I found a DRUPAL post which states the same issue with their product). Maybe, setting an environment variable somewhere to the cwd prior to the lavary/crunz script being called and then reset the cwd at the top of that script. I suppose there are other ways too but it should be fixed since crunz is primarily a cron solution. I gave my workaround in a prior post using symbolic links. I really didn't want to change the code to make it upgrade safe.

Thanks for all who chimed in with suggestions.

@PabloKowalczyk
Copy link
Collaborator

@eradin did passing absolute path to PHP binary solves issue also?

@eradin
Copy link
Author

eradin commented Feb 25, 2020

I'm not sure what you mean. I did try to replace the shebang with /usr/bin/php instead of the env php and that worked fine. Cron has it's own environment and path so using env is unpredictable. But hard coding /usr/bin/php is also unpredictable. The environment variable cwd is correct before the call to the second lavary/crunz. I think if you copy that to say CRUNZ_ROOT before the call to lavary/crunz and then pick it up in lavary/crunz, you can't go wrong in any case. I was going to try it out and if it worked post a pull request but I'm a little busy this week and can't get to it for several days.

@PabloKowalczyk
Copy link
Collaborator

I mean crontab entry like * * * * * cd /project/path && /absolute/path/to/bin/php vendor/bin/crunz s:r. With this entry you specify which PHP binary will be used. If this helps you I will change documentation.

@eradin
Copy link
Author

eradin commented Feb 25, 2020

No. That's because the error occurs in the lavary/crunz file (the vendor/bin/crunz call is fine). The shebang says env php so it will ignore your path entry and go with the environment. That is running cgi-fcgi. In a shared environment, I have no control over the cron environment.

@PabloKowalczyk
Copy link
Collaborator

Shebang will be used only if you call vendor/bin/crunz directly, if you specify PHP binary (/absolute/path/to/bin/php vendor/bin/crunz), specified binary will be used.

@eradin
Copy link
Author

eradin commented Feb 25, 2020

Maybe I'm not getting something here. vendor/bin/crunz is not a php file, it's a shell script. Running it through php just dumps it out to stdout. That file runs just fine as a shell script. It then calls lavary/crunz and that is a php file. It's also where the trouble begins because it's not using the sh interpreter (in my case). The standard php interpreter assumes the cwd is the path to the current running script. We need to force the php script to use the sh interpreter or you will have the same issues I have. What am I missing here?

@eradin
Copy link
Author

eradin commented Feb 25, 2020

Here, this is the solution:

vendor/bin/crunz line 14 insert:

export CRUNZ_ROOT=$PWD

lavary/crunz line 16 insert:

$ROOT = getenv('CRUNZ_ROOT');
if ($ROOT !== FALSE) {
chdir($ROOT);
}

@PabloKowalczyk
Copy link
Collaborator

I'm wondering why your vendor/bin/crunz is shell script? On Ubuntu and in Alpine container it is symlink to PHP file, are you on Windows? Maybe your Composer is very old?

I would like to understand reason of your issue, you wrote:

In my case, the CLI was using cli and cron was using cgi-fcgi

Does it mean that Cron was using FPM runtime? How can i reproduce your environment with Docker?

IMO the best solution will be to add new option to schedule:run, or whole Crunz, --cwd=/cwd/path, this will definitely reduce confusion and will be runtime independent. WDYT?

@eradin
Copy link
Author

eradin commented Feb 26, 2020

My dev system is windows and I propagate to a linux server. My composer version is 1.9 (8/2019) so it's pretty current. bin/crunz is most definitely a sh script and it does run on linux. I've never had a problem with propagating any php library from windows to linux.

I'm not sure you can reproduce it. My cpanel hosting has had other peculiar setups that don't seem to appear on my vps servers. I'm really alerting you that these kinds of things do occur and you should find a way to work around it. Instead of the CD ... in the cron command, I think having a command line arg is a great idea as long as you can search that path for the yml file and task directory. I implemented the environment variable approach from yesterday and it also works great and is transparent. Regarding your FPM question, If you php -v from the linux command line, it's states (cli). If you do the same from cron (I just added a job of php -v > phpver.log) and it reported cgi-fcgi which works differently than (sh). sh takes the current cwd while cgi changes the cwd to DIR.

Now, why do I have a sh script instead of a php script? Either way, it should work and as I've demonstrated, it can work transparently with a few lines of script. And that solution doesn't require any documentation changes.

Let me know if you have other questions.

@eradin
Copy link
Author

eradin commented Feb 26, 2020

Btw, here is what I have after composer install on windows.

bin/crunz.bat

@ECHO OFF
setlocal DISABLEDELAYEDEXPANSION
SET BIN_TARGET=%~dp0/../lavary/crunz/crunz
php "%BIN_TARGET%" %*

bin/crunz

#!/usr/bin/env sh

dir=$(cd "${0%[/\\]*}" > /dev/null; cd "../lavary/crunz" && pwd)

if [ -d /proc/cygdrive ]; then
    case $(which php) in
        $(readlink -n /proc/cygdrive)/*)
            # We are in Cygwin using Windows php, so the path must be translated
            dir=$(cygpath -m "$dir");
            ;;
    esac
fi

"${dir}/crunz" "$@"

@PabloKowalczyk
Copy link
Collaborator

Did you deploy your application by FTP/SCP/rsync/etc?

Your solution with modifying vendor/bin/crunz (which is binary file, not PHP file) is not portable at all, better solution for long term is --cwd option. Would you like to provide PR?

@PabloKowalczyk PabloKowalczyk added this to the v2.2 milestone Feb 27, 2020
@eradin
Copy link
Author

eradin commented Feb 27, 2020

Yes I use rsync. I don't understand what you mean the vendor/bin/cruz file is binary. It's a text shell script. At least my copy is. Anyway, I have it working with my patch but I would like a more permanent solution. If you think --cwd will do it, great.

@eradin
Copy link
Author

eradin commented Feb 27, 2020

I just tried to install crunz on the linux server and it is a very different setup than on windows. Perhaps there is a mismatch on how I am using crunz and the intended use. I have it as part of my application distro and I also check it into git. All of these symbolic links kind of break that development paradigm.

Was the intended use to make it a server deployment dependency? I suppose I could work that into my deployment script.

@PabloKowalczyk
Copy link
Collaborator

It is always better to install dependencies on target OS. When Crunz is installed on Linux, Composer creates symlink to Crunz main file and you can use /path/to/your/php-bin vendor/bin/crunz, of course course this is just a simplification. Solution will be a --cwd option.

@PabloKowalczyk PabloKowalczyk modified the milestones: v2.2, v2.3 Jun 18, 2020
@PabloKowalczyk PabloKowalczyk modified the milestones: v2.3, v2.NEXT Mar 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants