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

Error when executing the demo-applicaion: attempt to write a readonly database #2

Open
security-companion opened this issue Dec 21, 2020 · 4 comments
Assignees

Comments

@security-companion
Copy link

Hi,
I executed the get-script and then execute the source and manage.py commands.
When trying to login in the browser I am faced with an "attempt to write a readonly database" error.
I'm using Ubuntu 20.04.1 LTS 64-bit
I tried to adapt the permissions of the sqlite-file with chmod 777 filename but the error still persisted.

Stacktrace is the following:
`C(.venv) joachim@joachim-Aspire-S3:/home/django/basxconnect_demo$ python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
December 21, 2020 - 09:02:38
Django version 3.1.4, using settings 'basxconnect_demo.settings.dev'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Internal Server Error: /bread/login
Traceback (most recent call last):
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/dynamic_preferences/managers.py", line 212, in load_from_db
db_pref = db_prefs[preference.identifier()]
KeyError: 'general__sender_letterhead'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/query.py", line 573, in get_or_create
return self.get(**kwargs), False
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/query.py", line 429, in get
raise self.model.DoesNotExist(
dynamic_preferences.models.GlobalPreferenceModel.DoesNotExist: GlobalPreferenceModel matching query does not exist.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py", line 413, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: attempt to write a readonly database

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 202, in _get_response
response = response.render()
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/template/response.py", line 105, in render
self.content = self.rendered_content
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/template/response.py", line 83, in rendered_content
return template.render(context, self._request)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/template/backends/django.py", line 61, in render
return self.template.render(context)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/template/base.py", line 168, in render
with context.bind_template(self):
File "/usr/lib/python3.8/contextlib.py", line 113, in enter
return next(self.gen)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/template/context.py", line 244, in bind_template
updates.update(processor(self.request))
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/dynamic_preferences/processors.py", line 10, in global_preferences
return {'global_preferences': manager.all()}
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/dynamic_preferences/managers.py", line 203, in all
a.update(self.load_from_db(cache=True))
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/dynamic_preferences/managers.py", line 214, in load_from_db
db_pref = self.create_db_pref(
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/dynamic_preferences/managers.py", line 179, in create_db_pref
db_pref, created = self.model.objects.get_or_create(**kwargs)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/query.py", line 576, in get_or_create
return self._create_object_from_params(kwargs, params)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/query.py", line 610, in _create_object_from_params
obj = self.create(**params)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/query.py", line 447, in create
obj.save(force_insert=True, using=self.db)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/dynamic_preferences/models.py", line 67, in save
super(BasePreferenceModel, self).save(**kwargs)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/base.py", line 753, in save
self.save_base(using=using, force_insert=force_insert,
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/base.py", line 790, in save_base
updated = self._save_table(
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/base.py", line 895, in _save_table
results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/base.py", line 933, in _do_insert
return manager._insert(
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/query.py", line 1254, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1397, in execute_sql
cursor.execute(sql, params)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 98, in execute
return super().execute(sql, params)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 66, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/utils.py", line 90, in exit
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py", line 413, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: attempt to write a readonly database
[21/Dec/2020 09:02:44] "GET /bread/login?next=/ HTTP/1.1" 500 237484
Internal Server Error: /bread/login
Traceback (most recent call last):
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/dynamic_preferences/managers.py", line 212, in load_from_db
db_pref = db_prefs[preference.identifier()]
KeyError: 'general__sender_letterhead'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/query.py", line 573, in get_or_create
return self.get(**kwargs), False
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/query.py", line 429, in get
raise self.model.DoesNotExist(
dynamic_preferences.models.GlobalPreferenceModel.DoesNotExist: GlobalPreferenceModel matching query does not exist.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py", line 413, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: attempt to write a readonly database

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 202, in _get_response
response = response.render()
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/template/response.py", line 105, in render
self.content = self.rendered_content
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/template/response.py", line 83, in rendered_content
return template.render(context, self._request)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/template/backends/django.py", line 61, in render
return self.template.render(context)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/template/base.py", line 168, in render
with context.bind_template(self):
File "/usr/lib/python3.8/contextlib.py", line 113, in enter
return next(self.gen)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/template/context.py", line 244, in bind_template
updates.update(processor(self.request))
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/dynamic_preferences/processors.py", line 10, in global_preferences
return {'global_preferences': manager.all()}
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/dynamic_preferences/managers.py", line 203, in all
a.update(self.load_from_db(cache=True))
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/dynamic_preferences/managers.py", line 214, in load_from_db
db_pref = self.create_db_pref(
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/dynamic_preferences/managers.py", line 179, in create_db_pref
db_pref, created = self.model.objects.get_or_create(**kwargs)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/query.py", line 576, in get_or_create
return self._create_object_from_params(kwargs, params)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/query.py", line 610, in _create_object_from_params
obj = self.create(**params)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/query.py", line 447, in create
obj.save(force_insert=True, using=self.db)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/dynamic_preferences/models.py", line 67, in save
super(BasePreferenceModel, self).save(**kwargs)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/base.py", line 753, in save
self.save_base(using=using, force_insert=force_insert,
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/base.py", line 790, in save_base
updated = self._save_table(
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/base.py", line 895, in _save_table
results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/base.py", line 933, in _do_insert
return manager._insert(
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/query.py", line 1254, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1397, in execute_sql
cursor.execute(sql, params)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 98, in execute
return super().execute(sql, params)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 66, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/utils.py", line 90, in exit
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/django/basxconnect_demo/.venv/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py", line 413, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: attempt to write a readonly database
[21/Dec/2020 09:02:47] "GET /bread/login?next=/ HTTP/1.1" 500 237621`

@security-companion security-companion changed the title attempt to write a readonly database Error when executing the demo-applicaion: attempt to write a readonly database Dec 21, 2020
@tpokorra tpokorra self-assigned this Dec 22, 2020
@tpokorra
Copy link
Member

I have difficulty to reproduce this problem.
I have created now a CI job for devenv, https://lbs.solidcharity.com/package/basx/basxconnect/basxconnect-devenv, see the source here: https://github.com/basxsoftwareassociation/lbs-basxconnect/blob/master/basxconnect-devenv/setup.sh

That is using sqlite as well.
I am running python manage.py runserver as root.
The permissions of the sqlite database are like this:

-rw-r--r-- 1 django django 634880 Dec 22 11:54 /home/django/basxconnect_demo/db.sqlite3

I can login, and I can modify a person. (Saving does not seem to work, but when I reload the page, I can see that it was saved. but that is another topic/bug...)

This thread on Stackoverflow might give ideas: https://stackoverflow.com/questions/40703228/python-sqlite3-operationalerror-attempt-to-write-a-readonly-database

  • check permissions of the folder that contains the sqlite database
  • delete the sqlite database, and start again with migrate etc.

for me the permissions are like this:

(.venv) root@l005-build04lxd-lbs-solidcharity-com:/home/django/basxconnect_demo# ls -la
total 684
drwxr-xr-x 7 django django   4096 Dec 22 11:54 .
drwxr-xr-x 6 django django   4096 Dec 22 11:49 ..

Perhaps you are missing the x for others?

chmod a+x /home/django
chmod a+x /home/django/basxconnect_demo

@security-companion
Copy link
Author

Hi,
thanks for your comment. If I run the source and the python runserver command as root (sudo su -) then it works.

Perhaps it would be good to add a note at the end of the get-script that the commands need to be executed as root (although I think it would be better to being able to run the server without root for security reasons.
Greetings
Joejoe

tpokorra added a commit to basxsoftwareassociation/lbs-basxconnect that referenced this issue Dec 24, 2020
@tpokorra
Copy link
Member

You are right, we don't want the server to run as root.
I have now updated the documentation, and the test, to use the user django to run the server in the development environment.
I did get a message about permission errors to static css files, because they were generated as root. But once I fixed the ownership to django, I was able to run as user django.
I still was not able to reproduce your original error, with access permissions on the sqlite database.

I am just wondering, why the sqlite database was readonly: Perhaps you had another open connection to the database? Or a connection was not closed properly? sqlite can only have one concurrent write connection.

@saemideluxe
Copy link
Member

Not sure if I am too late here, but the problem comes from the following: A process accessing the database in write-mode (which is necessary at login time because session data is written to the database) needs to have write permission to the directory where the sqlite-file is located in. This is because sqlite creates a lock-file in the directory when the accessing process is writing to the file. This is necessary to handle concurrent writes in sqlite (see https://sqlite.org/lockingv3.html).
So the directory need the correct permissions as well. If you are not comfortable with giving certain permissions to the directory where the application code is located in you can easily change the path/directory of the sqlite file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants