vsoch / watchme

Reproducible watchers for research
https://vsoch.github.io/watchme/
Mozilla Public License 2.0
851 stars 32 forks source link

Can't find crontab at /usr/bin/crontab #59

Closed leliamesteban closed 5 years ago

leliamesteban commented 5 years ago

Expected Behavior

Scheduling a watcher with watchme schedule watcher @daily should schedule the watcher.

Actual Behavior

Instead, it complains that it can't find /usr/bin/crontab.

Traceback (most recent call last):
  File "/usr/local/bin/watchme", line 11, in <module>
    load_entry_point('watchme==0.0.26', 'console_scripts', 'watchme')()
  File "/usr/local/lib/python3.7/site-packages/watchme/client/__init__.py", line 346, in main
    main(args, extras)
  File "/usr/local/lib/python3.7/site-packages/watchme/client/schedule.py", line 44, in main
    watcher.schedule(minute, hour, month, day, weekday, force=args.force)
  File "/usr/local/lib/python3.7/site-packages/watchme/watchers/schedule.py", line 132, in schedule
    cron = self.get_crontab()
  File "/usr/local/lib/python3.7/site-packages/watchme/watchers/schedule.py", line 68, in get_crontab
    return CronTab(user=True)
  File "/usr/local/lib/python3.7/site-packages/crontab.py", line 227, in __init__
    self.read(tabfile)
  File "/usr/local/lib/python3.7/site-packages/crontab.py", line 284, in read
    (out, err) = open_pipe(CRONCMD, l='', **self.user_opt).communicate()
  File "/usr/local/lib/python3.7/site-packages/crontab.py", line 189, in open_pipe
    return sp.Popen(args, stdout=sp.PIPE, stderr=sp.PIPE, env=env)
  File "/usr/lib64/python3.7/subprocess.py", line 775, in __init__
    restore_signals, start_new_session)
  File "/usr/lib64/python3.7/subprocess.py", line 1522, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: '/usr/bin/crontab': '/usr/bin/crontab'

Steps to Reproduce

I followed all the steps on the Getting Started guide

sudo pip3 install watchme

watchme init

watchme create nicoli

watchme add-task nicoli task-singularity-release url@https://www.nicolishop.com/es/es/coleccion-ropa-para-hombres

watchme activate nicoli

watchme run nicoli

Output:

[1/1] |===================================| 100.0% 
ERROR Error running task.

watchme schedule nicoli @daily

Output: (shown under Actual behaviour)

Context

This is a Linux distribution that allows different programs / packages on the same system to be provided by different Linux distributions).

In this case, watchme is provided by Fedora (because I installed it with pip3, which is provided by Fedora), while crontab is provided by Debian. I will investigate if the issue is caused by Bedrock

Failure Logs

[ log or files here. If relevant, include a screenshot]

Possible Fix

Sometimes Bedrock exhibits these types of problems where one program tries to access another program in a hardcoded location (eg. /usr/bin), when it's actually in eg. /bedrock/cross/bin. However, as far as I can tell (looking at ls -l and file output, /usr/bin/crontab is actually there.

I will investigate if installing crontab from Fedora fixes the problem.

I also noticed that a package by the same name crontab exists in the python repositories and can be installed using pip. I installed it with sudo pip3 install crontab and I get a different error message now.

Traceback (most recent call last):
  File "/usr/local/bin/watchme", line 11, in <module>
    load_entry_point('watchme==0.0.26', 'console_scripts', 'watchme')()
  File "/usr/local/lib/python3.7/site-packages/watchme/client/__init__.py", line 346, in main
    main(args, extras)
  File "/usr/local/lib/python3.7/site-packages/watchme/client/schedule.py", line 44, in main
    watcher.schedule(minute, hour, month, day, weekday, force=args.force)
  File "/usr/local/lib/python3.7/site-packages/watchme/watchers/schedule.py", line 132, in schedule
    cron = self.get_crontab()
  File "/usr/local/lib/python3.7/site-packages/watchme/watchers/schedule.py", line 68, in get_crontab
    return CronTab(user=True)
TypeError: __init__() got an unexpected keyword argument 'user'
vsoch commented 5 years ago

Thanks for the detailed issue! So - watchme (via pypi) is agnostic to the operating system - pypi should work on ubuntu, fedora, etc. Pip is typically linked to a Python version, so unless python is different on bedrock, it shouldn't be an issue there.

Now let's talk about crontab - the crontab that you install with pip will serve as a wrapper to your system's crontab. So first I would ensure that you have crontab installed on your host, period. For example:

$ which crontab
/usr/bin/crontab
$ crontab -l
@hourly /home/vanessa/anaconda3/bin/watchme run air-quality # watchme-air-quality
...

And then if you did pip install crontab, this isn't the one that is used by watchme (hence the error for the unexpected keyword). The install should be for python-crontab:

$ pip freeze | grep crontab
python-crontab==2.3.6

So first try uninstalling that different version. I think what we would want to do is created a symbolic link from wherever your crontab is, to where it's expected to be. Let me know where that is and I can help further.

leliamesteban commented 5 years ago

Sorry I wasn't clear enough. With this: "/usr/bin/crontab is actually there" I meant that it is installed on my host, and that which crontab and crontab -l both return what we expect them too.

I uninstalled crontab from pip, and now both pip3 freeze | grep crontab and pip freeze | grep crontab give me:

python-crontab==2.3.6

To recap, crontab (the Linux package) exists and is at /usr/bin/crontab, as I would expect. I'm still confused as to why watchme can't find it there, or where else it would expect to find it.

vsoch commented 5 years ago

okay, now you are back to having the correct packages. Let's take a look at this error:

Traceback (most recent call last):
  File "/usr/local/bin/watchme", line 11, in <module>
    load_entry_point('watchme==0.0.26', 'console_scripts', 'watchme')()
  File "/usr/local/lib/python3.7/site-packages/watchme/client/__init__.py", line 346, in main
    main(args, extras)
  File "/usr/local/lib/python3.7/site-packages/watchme/client/schedule.py", line 44, in main
    watcher.schedule(minute, hour, month, day, weekday, force=args.force)
  File "/usr/local/lib/python3.7/site-packages/watchme/watchers/schedule.py", line 132, in schedule
    cron = self.get_crontab()
  File "/usr/local/lib/python3.7/site-packages/watchme/watchers/schedule.py", line 68, in get_crontab
    return CronTab(user=True)
  File "/usr/local/lib/python3.7/site-packages/crontab.py", line 227, in __init__
    self.read(tabfile)
  File "/usr/local/lib/python3.7/site-packages/crontab.py", line 284, in read
    (out, err) = open_pipe(CRONCMD, l='', **self.user_opt).communicate()
  File "/usr/local/lib/python3.7/site-packages/crontab.py", line 189, in open_pipe
    return sp.Popen(args, stdout=sp.PIPE, stderr=sp.PIPE, env=env)
  File "/usr/lib64/python3.7/subprocess.py", line 775, in __init__
    restore_signals, start_new_session)
  File "/usr/lib64/python3.7/subprocess.py", line 1522, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: '/usr/bin/crontab': '/usr/bin/crontab'

It's not logical that you are reporting the executable to be there, but Python doesn't find it. Question - is there a docker image that can reproduce the environment on your host so that I can take a look?

vsoch commented 5 years ago

Is this Bedrock? https://hub.docker.com/r/weahead/bedrock/

vsoch commented 5 years ago

The base of that container is alpine linux - could you tell me the underlying OS of what you are using?

vsoch commented 5 years ago

I need to be able to reproduce your error, if you are able to provide a means, because the error message is not logical.

leliamesteban commented 5 years ago

No, that's a wordpress boilerplate. Bedrock is a linux distribution. First I installed Debian 9. Then I ran a script that allowed me to install Fedora as well. So now I'm effectively running Fedora and Debian at the same time.

This means that I can install packages from more than one linux distribution at the same time. However, to simplify things, I can just install them from one, so effectively it'll be like I'm running Fedora.

vsoch commented 5 years ago

That's really cool! Let me see if I can reproduce what you've done with Docker.

vsoch commented 5 years ago

Which script did you use from here? https://raw.githubusercontent.com/bedrocklinux/bedrocklinux-userland/0.7/releases

vsoch commented 5 years ago

(I assume the first)

leliamesteban commented 5 years ago

It would be cool if you could do that, and helpful for debugging the issue. However, I can't find any examples of what you're trying to do on the internet, and I know from firsthand experience that running Bedrock Linux inside a chroot is not explicitly supported (although possible). I don't know what it'll be like to try and get it inside a Docker container, but maybe you can talk with the maintainer if you have any trouble

leliamesteban commented 5 years ago

Yes, I used the first (0.7.6-x86_64

vsoch commented 5 years ago

Just curious - when you run Python, is there any customization of the path? For example, if you (using the same Python watchme is installed for):

import os
os.path.exists("/usr/bin/crontab")

Does it tell you the file exists then? I'm also wondering if there are any updates for python versions 3.7* that might be leading to this. My gut is saying it's related to this custom OS, but it's hard to say without testing.

leliamesteban commented 5 years ago

I found something interesting.

python3.5 has no problems finding the file.

However, python3.7 says that nothing exists at /usr/bin/crontab

leliamesteban commented 5 years ago

No clue why, in fact I almost didn't test it because I assumed that on my system python3 was an alias to python3.7, but they're actually different executables

leliamesteban commented 5 years ago

In fact, python3.7 lives at /bedrock/cross/bin, whereas python3 is at /usr/bin

vsoch commented 5 years ago

Ah, we've found something! Are you able to install watchme to the specific version of Python that does see crontab? I bet that is the issue. And now you have me interested in this Bedrock Linux, I'm going to play around with it this weekend :) Just curious, what do you use it for?

leliamesteban commented 5 years ago

Yes, I'll try installing watchme to python3.5, and then we can figure out how to get it working on python 3.7.

vsoch commented 5 years ago

ok! Keep me updated :)

leliamesteban commented 5 years ago

I use Bedrock because I got tired of dealing with the inconsistencies between Linux distributions. I wanted to benefit from Arch Linux's user repository, while at the same time be able to use a graphical installer to install the distribution. Also, for example the FAI project is convenient for installing Linux with very little fuss, but it only supports Debian. With Bedrock I don't have to commit to using Debian instead of Arch, I can use both!

leliamesteban commented 5 years ago

This issue also made me realize that packages from the base distribution (I hope I don't confuse you with the terminology; in this case I mean Debian, because I installed it first) live in /usr/bin, while packages from any distributions you install after Bedrock (like Fedora, Arch) live in /bedrock/cross.

vsoch commented 5 years ago

wow, it really is having multiple operating systems! :popcorn:

leliamesteban commented 5 years ago

Yeah! Every once in a while I run into bugs like this where some programs can't find other programs, but other than that it's really transparent. You just use any linux distribution you want at the same time, with basically no conflict

leliamesteban commented 5 years ago

I installed cronie on Fedora. Fixed the issue!

I'm gonna talk to Bedrock's maintainer because I still don't understand why watchme doesn't see crontab unless it's provided by Fedora. After that I'll close the issue

Thanks!

vsoch commented 5 years ago

Woot! And you are very welcome! This one was fun, and I'm going to check out Bedrock too.