pythonpython-3.xpipvagrantdjango-cron

Permission denied while installing django-cron in Vagrant


When running pip install django-cron I get the following error:

ERROR: Error [Errno 13] Permission denied: '/vagrant/.venv/bin/python' while executing command python setup.py egg_info
ERROR: Could not install packages due to an EnvironmentError: [Errno 13] Permission denied: '/vagrant/.venv/bin/python'
Consider using the `--user` option or check the permissions.

However, if I use --user, I get a different error saying:

ERROR: Can not perform a '--user' install. User site-packages are not visible in this virtualenv.

My venv is activated.

When I previously tried installing libraries, everything worked, if I use the sudo command I get the following warning:

WARNING: The directory '/home/vagrant/.cache/pip' or its parent directory is not owned or is not writable by the current user. The cache has been disabled. Check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag. 

Using -H doesn't resolve the issue sadly, I am not sure how I can change my access to the .venv file, any help would be appreciated.

I only get this error for Python modules django-cron and django-crontab, but other modules like pillow can be installed successfully.

Edit 4: My setup is a bit janky, as I am using Vagrant, but I have PyCharm Community Editon, so I end up downloading the packages twice, once just so the editor would recognize it and another time for Vagrant where I run the program, and when I did this in PyCharm, it worked in PyCharm.

This is the Vagrantfile I used:

Vagrant.configure("2") do |config|
  config.vm.box = "bento/ubuntu-18.04"

  config.vm.network "forwarded_port", guest: 8080, host: 8080

  config.vm.provision "shell", inline: <<-SHELL
    sudo apt-get install python3-distutils -y
    curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
    sudo python3 get-pip.py
    rm get-pip.py
    sudo pip install virtualenv
    cd /vagrant 
    virtualenv -p /usr/bin/python3 .venv --always-copy
    echo "cd /vagrant && source /vagrant/.venv/bin/activate" >> /home/vagrant/.profile
  SHELL
end

Solution

  • By default, Vagrant provisioning scripts are executed as root. Since you create the virtual environment during the provisioning the directories are owned by root and not accessible for the normal user (vagrant).

    To solve this, you should set the shell provisioning option "privileged" to false.

    Change this line:

    config.vm.provision "shell", inline: <<-SHELL
    

    to:

    config.vm.provision "shell", privileged: false, inline: <<-SHELL
    

    Alternatively, you could modify your provisioning script to run the virtualenv command as the vagrant user using the following command:

    sudo -u vagrant virtualenv -p /usr/bin/python3 .venv --always-copy
    

    UPDATE:

    Although the above is generally true, it's not the cause of the problem in your case, since you installed the virtual environment inside /vagrant, which is a virtual mount of the directory on your host machine (the directory where your Vagrantfile is stored). Normal file permissions do not apply, or at least not in the usual way, for this directory.

    It seems that the Python modules django-cron and django-crontab have an issue with this mount, for whatever reason (might be a bug).

    Creating the virtual environment inside the VM file system instead of the host file system solves the problem. You could use the following Vagrantfile. I tested this and I could install django-cron without errors.

    Vagrant.configure("2") do |config|
      config.vm.box = "bento/ubuntu-18.04"
    
      config.vm.network "forwarded_port", guest: 8080, host: 8080
    
      config.vm.provision "shell", privileged: false, inline: <<-SHELL
        sudo apt-get install python3-distutils -y
        curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
        sudo python3 get-pip.py
        rm get-pip.py
        sudo pip install virtualenv
        virtualenv -p /usr/bin/python3 /home/vagrant/venv --always-copy
        echo "cd /vagrant && source /home/vagrant/venv/bin/activate" >> /home/vagrant/.profile
      SHELL
    end