django manage.py script messed up directory permissions - python

I have a script that checks a json file and downloads photos to a folder.
This bit checks if the directory exists and if not, creates it:
folder = media_root + 'photos/' + now.strftime('%Y') + '/' + now.strftime('%m') + '/' + now.strftime('%d')
if not os.path.isdir(folder):
os.makedirs(folder)
everything worked like it should, but now the folder can't be written through the django admin interface, giving the error OSError: [Errno 13] Permission denied: media/photos/2014/08/31/OneOf.jpg
The only way this works is if I set the permissions to be writable by everyone.
I checked and gunicorn is running with user nobody, and this never caused a problem before.
What could have caused this issue and how do I stop it from happening in the future?
EDIT:
I tried out the suggestions bellow but running the script as nobody only returned an error:
File "./manage.py", line 8, in <module>
from django.core.management import execute_from_command_line
ImportError: No module named django.core.management
I also checked and the other folders, created by the django-admin interface, are also owned by root.
RESOLUTION:
the os.makedirs commands changed the whole directory tree to be owned by root, which is why that even with the same permissions as other folders django couldn't write to that directory.
To keep it from happening again the solution is to restore ownership to that directory tree once the new folder is created.

The problem is that you are running the script as root.
The user that you run a program with is the same user that owns any files created by that program.
Once you run a program as root, any output will also be owned by the root user, which means the user that is running the django app will not have access to those files.
You should run the manage.py script as the same user that is running your web app (nobody) so that files created are then readable by the gunicorn process - and by extension, django.

to unspool your first issue:
created some data with bad perms
$ sudo chown -R www-data:www-data /full/path/to/media
running manage.py as the webserver user
$ sudo -u www-data ./manage.py <your-management-command>
Note: If sudo is not set up, you should set it up.

Related

Python Heroku allow pushed .exe to run - OSError: [Errno 13] Permission denied

I had to push an .exe file to heroku to be able to create invoice pdfs. It works localy without any problems but on heroku I get an error:
OSError: [Errno 13] Permission denied
Probably because I am not allowed to execute .exe files. So I need somehow to create a rule that this file is allowed to execute.
I pushed wkhtmltopdf.exe to heroku and I access this file in my method to create a pdf:
MYDIR = os.path.dirname(__file__)
path_wkthmltopdf = os.path.join(MYDIR + "/static/executables/", "wkhtmltopdf.exe")
config = pdfkit.configuration(wkhtmltopdf=path_wkthmltopdf)
Was not able to find a solution yet.
EDIT:
Tryed giving permission with chmod through heroku bash and also adding a linux executable but still the same error:
~/static/executables $ chmod a+x wkhtmltopdf-linux.exe
~ $ chmod a+x static/executables/wkhtmltopdf-linux.exe
Using sudo gave me:
bash: sudo: command not found
I'm not very familiar with heroku, but if you can somehow get access to terminal of environment of your application (for example ssh to your server), you need to change permissions of that file so it can be executed. To do that, you need to run in that terminal:
sudo chmod a+x /path/to/file/FILENAME
Also,i'm pretty sure your app on Heroku runs on Linux, specifically on Ubuntu, since it's the default (link)
It means there might be difficulties with running Windows executables.
Okay I managed to fix this with a buildpack. In addition wkhtmltopdf-pack must be installed and added to the requirements.txt.
Then you have to set a config var in heroku for the wkhtmltopdf executable which will be generated from the files provided in the buildpack. Do not search for an .exe file.
heroku config:set WKHTMLTOPDF_BINARY=wkhtmltopdf-pack
You can see all your config vars also in the heroku dashboard under settings, you can also create it there and not use the CLI.
Then you have to tell the pdfkit configuration where to find the WKHTMLTOPDF_BINARY:
In my config.py:
import subprocess
WKHTMLTOPDF_CMD = subprocess.Popen(
['which', os.environ.get('WKHTMLTOPDF_BINARY', 'wkhtmltopdf')], # Note we default to 'wkhtmltopdf' as the binary name
stdout=subprocess.PIPE).communicate()[0].strip()
For the pdfkit configuration:
config = pdfkit.configuration(wkhtmltopdf=app.config['WKHTMLTOPDF_CMD'])
Now you should be able to create the pdf, example:
the_pdf = pdfkit.from_string("something", False, configuration=config)
Credit to this tutorial:
https://artandlogic.com/2016/12/generating-pdfs-wkhtmltopdf-heroku/

Git command when translating files in Django

I have an existing application in Django.
I want to add a translation on the page.
On page I have:
{% trans 'Projects'%}
In .po file I added:
#: templates/staff/site.html: 200
msgid "Projects"
msgid "Projekty"
Then executes the command:
django-admin.py compilemessages -l pl
After this command, I get an error:
CommandError: This Should Be Run script from the Django Git checkout or your project or app tree, or with the settings Specified module.
$ python manage.py compilemessages --settings nsp.settings
CommandError: This script should be run from the Django Git checkout or your project or app tree, or with the settings module specified.
I have got this error while I truly was inside project root folder.
The problem was, that I was running this command without python manage.py makemessages first.
The error message is misleading.
The error holds the answer, you could be running the script from anywhere so it cannot know which files to compile. Run the command from the project directory or specify the settings and you should be fine.
If you are using docker containers to build and deploy your application you should copy folder:
conf/
from root folder of your django project.
with the conf folder you should see i.e:
processing file django.po in /gamma/conf/locale/en/LC_MESSAGES
processing file django.po in /gamma/conf/locale/es/LC_MESSAGES
processing file django.po in /gamma/conf/locale/pt_BR/
without the conf folder you should see a clueless message like that:
CommandError: This script should be run from the Django Git checkout or your project or app tree, or with the settings module specified.
The error message is saying that it could not find the translations files where it expected them to be. Check that everything is correctly setup:
LOCALE_PATHS is defined in your settings.py
the files exist in the folder defined above (created by running python manage.py makemessages)
actually the error goes away even with just an empty locales folder
the compilemessages command is run from the project root folder
If you haven't set LOCALE_PATHS in your settings file, you need to do so:
import os
LOCALE_PATHS = [os.path.join(BASE_DIR, 'locale')]

Linux. Heroku-Django. Collectstatic read-only file system

I need help from someone who understands linux. I can't push my staticfiles to Heroku (I'm trying to use whitenoise and not Amazon S3 or any CDN). The error is rather simple, when I try to push to heroku I get:
Preparing static assets
Running collectstatic...
Traceback (most recent call last):
OSError: [Errno 30] Read-only file system: '/assets'
So, I can't run collectstatic cause I don't have permissions. If I do sudo git push heroku master I get another error: Permission denied (publickey) And I guess that is cause 'sudo' uses a different SSH key.
I've tried to change permissions to the folder from the file manager and I've also tried from bash:
sudo chmod 777 -R static
static is the parent folder: static/assets.
So... how can I solve this? Any help will be greatly appreciated.
I don't think the problem is pushing content to Heroku, specifically. You're trying to save assets to a root folder on the virtual machine, which your'e not allowed to do.
Traditionally with Heroku, you'd set the static assets directory to something like staticfiles (not /staticfiles or /assets). When Heroku deploys the app to its virtual machines (what it calls "dynos") it works in its own little directory (I think it's /app), so all the directories you specify in your settings.py file are relative to that directory.
Try setting the static files root directory to staticfiles or assets without the slash, and that should work.

Permission error uploading user image via Django. The server is running as root, and the directory has 775 permissions

I am getting the following error when attempting to upload an image, when creating a new record in the admin interface.
Permission denied: '/home/jeffy/django_files/django_test/static/uploaded_files/1407616465_2016587_61DjIaZQI8L.jpg'
Relevant settings.py variables:
STATIC_ROOT = "/home/jeffy/django_files/django_test/static/"
MEDIA_ROOT=STATIC_ROOT
The output of
ls -l /home/jeffy/django_files/django_test/static/
is
drwxrwxr-x 2 jeffy jeffy 4096 Aug 9 16:32 uploaded_files
And the servers were started as user jeffy:
jeffy#originaldjangster:/etc/nginx/sites-available$ sudo service nginx start
jeffy#originaldjangster:/etc/nginx/sites-available$ sudo /home/jeffy/django_files/django_test_venv/bin/gunicorn -c /home/jeffy/django_files/django_test_venv/gunicorn_config.py django_test.wsgi
root
I placed this code at the end of settings.py
import getpass
print(getpass.getuser())
which is why "root" prints out after the gunicorn server is started.
Why can't this file be uploaded?
Here's the original gunicorn_config.py file:
command = '/home/jeffy/django_files/django_test_venv/bin/gunicorn'
pythonpath = '/home/jeffy/django_files/django_test'
bind = '127.0.0.1:8001'
workers = 1
user = 'nobody'
Changing nobody to jeffy makes it work (although it balked at the static and media directories being equal...I made a media folder next to the static one).
This setup is only for me to show off my Django chops. If this were a production environment, I do get that running the server as root is a bad idea.
Not sure how "bad" this setup really is, but it's working at least so far...

Changing file permissions for Apache - Django

I'm trying to modify file permissions in Linux so that Apache and Django have permission to read and write to the database. The path of my database file is
/var/www/tbg/database/database.sqlite3
I use these commands
chown www-data:www-data /var/www/tbg
chown www-data:www-data /var/www/tbg/database/database.sqlite3
Yet I get the same error (same error as is described here: sqlite3.OperationalError: unable to open database file).
To make sure the permissions are still not there, I can't paste content or create new folders. I can in the the subfolders of /tbg/, though, but not in /tbg/ itself.
I found the answer. I had neglected to change the file permissions of the directories inside /tbg/! With ls -l I was able to figure this out and then I typed
chmod www-data:www-data foldername
to enable apache to read and write to the directories. This must be done for every directory under your project's name (in my case /tbg/) -- and in every subdirectory under every subdirectory!

Categories