Re: Migrating mailman3 to latest ubuntu lts
by Helio Loureiro
Hi,
Indeed it was the configuration. It was placed into
/etc/mailman3/mailman-web.py. After a I changed to
/etc/mailman3/settings.py a few things advanced a little bit more.
I had to figure out how to fix mysqlclient installation since there isn't a
mention about it and the simple "pip install mysqclient" was breaking with
pkg-config issues. But it did work at the end.
Now I can see further messages on mailman3-web than before.
(venv) mailman@new-server ~ (v3.3.9)> mailman-web migrate
System check identified some issues:
WARNINGS:
account.EmailAddress: (models.W036) MariaDB does not support unique
constraints with conditions.
HINT: A constraint won't be created. Silence this warning if you don't care
about it.
account.EmailAddress: (models.W043) MariaDB does not support indexes on
expressions.
HINT: An index won't be created. Silence this warning if you don't care
about it.
Operations to perform:
Apply all migrations: account, admin, auth, contenttypes,
django_mailman3, django_q, hyperkitty, postorius, sessions, sites,
socialaccount
Running migrations:
Applying account.0004_alter_emailaddress_drop_unique_email...Traceback
(most recent call last):
File
"/local/mailman/venv/lib/python3.10/site-packages/django/db/backends/utils.py",
line 89, in _execute
return self.cursor.execute(sql, params)
File
"/local/mailman/venv/lib/python3.10/site-packages/django/db/backends/mysql/base.py",
line 75, in execute
return self.cursor.execute(query, args)
File
"/local/mailman/venv/lib/python3.10/site-packages/MySQLdb/cursors.py", line
179, in execute
res = self._query(mogrified_query)
File
"/local/mailman/venv/lib/python3.10/site-packages/MySQLdb/cursors.py", line
330, in _query
db.query(q)
File
"/local/mailman/venv/lib/python3.10/site-packages/MySQLdb/connections.py",
line 257, in query
_mysql.connection.query(self, query)
MySQLdb.OperationalError: (2013, 'Lost connection to MySQL server during
query')
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/local/mailman/venv/bin/mailman-web", line 8, in <module>
sys.exit(main())
File
"/local/mailman/venv/lib/python3.10/site-packages/mailman_web/manage.py",
line 90, in main
execute_from_command_line(sys.argv)
File
"/local/mailman/venv/lib/python3.10/site-packages/django/core/management/__init__.py",
line 446, in execute_from_command_line
utility.execute()
File
"/local/mailman/venv/lib/python3.10/site-packages/django/core/management/__init__.py",
line 440, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File
"/local/mailman/venv/lib/python3.10/site-packages/django/core/management/base.py",
line 402, in run_from_argv
self.execute(*args, **cmd_options)
File
"/local/mailman/venv/lib/python3.10/site-packages/django/core/management/base.py",
line 448, in execute
output = self.handle(*args, **options)
File
"/local/mailman/venv/lib/python3.10/site-packages/django/core/management/base.py",
line 96, in wrapped
res = handle_func(*args, **kwargs)
File
"/local/mailman/venv/lib/python3.10/site-packages/django/core/management/commands/migrate.py",
line 349, in handle
post_migrate_state = executor.migrate(
File
"/local/mailman/venv/lib/python3.10/site-packages/django/db/migrations/executor.py",
line 135, in migrate
state = self._migrate_all_forwards(
File
"/local/mailman/venv/lib/python3.10/site-packages/django/db/migrations/executor.py",
line 167, in _migrate_all_forwards
state = self.apply_migration(
File
"/local/mailman/venv/lib/python3.10/site-packages/django/db/migrations/executor.py",
line 252, in apply_migration
state = migration.apply(state, schema_editor)
File
"/local/mailman/venv/lib/python3.10/site-packages/django/db/migrations/migration.py",
line 130, in apply
operation.database_forwards(
File
"/local/mailman/venv/lib/python3.10/site-packages/django/db/migrations/operations/fields.py",
line 235, in database_forwards
schema_editor.alter_field(from_model, from_field, to_field)
File
"/local/mailman/venv/lib/python3.10/site-packages/django/db/backends/base/schema.py",
line 788, in alter_field
self._alter_field(
File
"/local/mailman/venv/lib/python3.10/site-packages/django/db/backends/base/schema.py",
line 858, in _alter_field
self.execute(self._delete_unique_sql(model, constraint_name))
File
"/local/mailman/venv/lib/python3.10/site-packages/django/db/backends/base/schema.py",
line 199, in execute
cursor.execute(sql, params)
File
"/local/mailman/venv/lib/python3.10/site-packages/django/db/backends/utils.py",
line 67, in execute
return self._execute_with_wrappers(
File
"/local/mailman/venv/lib/python3.10/site-packages/django/db/backends/utils.py",
line 80, in _execute_with_wrappers
return executor(sql, params, many, context)
File
"/local/mailman/venv/lib/python3.10/site-packages/django/db/backends/utils.py",
line 84, in _execute
with self.db.wrap_database_errors:
File
"/local/mailman/venv/lib/python3.10/site-packages/django/db/utils.py", line
91, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File
"/local/mailman/venv/lib/python3.10/site-packages/django/db/backends/utils.py",
line 89, in _execute
return self.cursor.execute(sql, params)
File
"/local/mailman/venv/lib/python3.10/site-packages/django/db/backends/mysql/base.py",
line 75, in execute
return self.cursor.execute(query, args)
File
"/local/mailman/venv/lib/python3.10/site-packages/MySQLdb/cursors.py", line
179, in execute
res = self._query(mogrified_query)
File
"/local/mailman/venv/lib/python3.10/site-packages/MySQLdb/cursors.py", line
330, in _query
db.query(q)
File
"/local/mailman/venv/lib/python3.10/site-packages/MySQLdb/connections.py",
line 257, in query
_mysql.connection.query(self, query)
django.db.utils.OperationalError: (2013, 'Lost connection to MySQL server
during query')
Which seems to be complaining with DB credentials. But they're properly
set and it works via mysql command line.
(venv) mailman@new-server ~ (v3.3.9)> mysql -umailman3web -p mailman3web
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 32
Server version: 10.6.12-MariaDB-0ubuntu0.22.04.1 Ubuntu 22.04
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input
statement.
MariaDB [mailman3web]> show tables;
+-------------------------------+
| Tables_in_mailman3web |
+-------------------------------+
| account_emailaddress |
| account_emailconfirmation |
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_mailman3_maildomain |
| django_mailman3_profile |
| django_migrations |
| django_q_ormq |
| django_q_schedule |
| django_q_task |
| django_session |
| django_site |
| hyperkitty_attachment |
| hyperkitty_email |
| hyperkitty_favorite |
| hyperkitty_lastview |
| hyperkitty_mailinglist |
| hyperkitty_profile |
| hyperkitty_sender |
| hyperkitty_tag |
| hyperkitty_tagging |
| hyperkitty_thread |
| hyperkitty_threadcategory |
| hyperkitty_vote |
| socialaccount_socialaccount |
| socialaccount_socialapp |
| socialaccount_socialapp_sites |
| socialaccount_socialtoken |
+-------------------------------+
34 rows in set (0.000 sec)
On the /etc/mailman3/settings.py:
(venv) mailman@seliius26224 ~ (v3.3.9)> cat /etc/mailman3/settings.py |
grep -v "#" | grep -v '^$'
from mailman_web.settings.base import *
from mailman_web.settings.mailman import *
ADMINS = (
('Mailman Suite Admin', 'root@localhost'),
)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mailman3web',
'USER': 'mailman3web',
'PASSWORD': '*******************',
'HOST': 'localhost',
'PORT': '3306',
}
}
STATIC_ROOT = '/local/mailman/web/static'
COMPRESS_ENABLED = True
LOGGING['handlers']['file']['filename'] =
'/local/mailman/web/logs/mailmanweb.log'
ALLOWED_HOSTS = [
"127.0.0.1",
"*"
]
CSRF_TRUSTED_ORIGINS = [
]
SITE_ID = 1
SECRET_KEY = '****************************************'
DEFAULT_FROM_EMAIL = 'admin(a)mailman.domain.com'
SERVER_EMAIL = 'admin(a)mailman.domain.com'
MAILMAN_REST_API_URL = 'http://localhost:8001'
MAILMAN_REST_API_USER = 'restadmin'
MAILMAN_REST_API_PASS = '***************************'
MAILMAN_ARCHIVER_KEY = '****************************'
MAILMAN_ARCHIVER_FROM = ('127.0.0.1', '::1', '1.2.3.4')
HAYSTACK_CONNECTIONS = {
'default': {
'PATH': "/opt/mailman/web/xapian_index",
'ENGINE': 'xapian_backend.XapianEngine'
},
}
And /local/mailman/web/logs/mailmanweb.log is empty.
Best Regards,
Helio Loureiro
https://helio.loureiro.eng.br
https://github.com/helioloureiro
https://mastodon.social/@helioloureiro
On Sun, 17 Dec 2023 at 16:35, Mark Sapiro <mark(a)msapiro.net> wrote:
> On 12/16/23 10:12 AM, Helio Loureiro wrote:
> > Hi,
> >
> > Well... not that good. Now it is mailman3-web that doesn't work.
> >
> > mailman@new-machine ~ (v3.3.9)> source venv/bin/activate.fish
> > (venv) mailman@new-machine ~ (v3.3.9)> mailman-web
> >
> > Type 'mailman-web help <subcommand>' for help on a specific subcommand.
> >
> > Available subcommands:
> >
> > [django]
> > check
> > compilemessages
> > createcachetable
> > dbshell
> > diffsettings
> > dumpdata
> > flush
> > inspectdb
> > loaddata
> > makemessages
> > makemigrations
> > migrate
> > optimizemigration
> > runserver
> > sendtestemail
> > shell
> > showmigrations
> > sqlflush
> > sqlmigrate
> > sqlsequencereset
> > squashmigrations
> > startapp
> > startproject
> > test
> > testserver
>
> This response indicates that `mailman-web` is not getting settings.py.
> Have you configured /etc/mailman3/settings.py? See
> <
> https://docs.mailman3.org/en/latest/install/virtualenv.html#initial-configu…
> >.
>
> > (venv) mailman@new-machine ~ (v3.3.9)> mailman-web check
> > System check identified no issues (0 silenced).
> > (venv) mailman@new-machine ~ (v3.3.9)> mailman-web check migrate
>
> You should run `mailman-web migrate` not `mailman-web check migrate`
> plus others. See
> <
> https://docs.mailman3.org/en/latest/install/virtualenv.html#run-database-mi…>
>
> et.seq. but first you need the appropriate settings so `mailman-web`
> returns something like
> ```
> $ mailman-web
>
> Type 'mailman-web help <subcommand>' for help on a specific subcommand.
>
> Available subcommands:
>
> [account]
> account_unsetmultipleprimaryemails
>
> [auth]
> changepassword
> createsuperuser
>
> [compressor]
> compress
> mtime_cache
>
> [contenttypes]
> remove_stale_contenttypes
>
> [django]
> check
> compilemessages
> createcachetable
> dbshell
> diffsettings
> dumpdata
> flush
> inspectdb
> loaddata
> makemessages
> makemigrations
> migrate
> optimizemigration
> sendtestemail
> shell
> showmigrations
> sqlflush
> sqlmigrate
> sqlsequencereset
> squashmigrations
> startapp
> startproject
> test
> testserver
>
> [django_extensions]
> admin_generator
> clean_pyc
> clear_cache
> compile_pyc
> create_command
> create_jobs
> create_template_tags
> delete_squashed_migrations
> describe_form
> drop_test_database
> dumpscript
> export_emails
> find_template
> generate_password
> generate_secret_key
> graph_models
> list_model_info
> list_signals
> mail_debug
> managestate
> merge_model_instances
> notes
> pipchecker
> print_settings
> print_user_for_session
> raise_test_exception
> reset_db
> reset_schema
> runjob
> runjobs
> runprofileserver
> runscript
> runserver_plus
> set_default_site
> set_fake_emails
> set_fake_passwords
> shell_plus
> show_template_tags
> show_urls
> sqlcreate
> sqldiff
> sqldsn
> sync_s3
> syncdata
> unreferenced_files
> update_permissions
> validate_templates
>
> [django_q]
> qcluster
> qinfo
> qmemory
> qmonitor
>
> [haystack]
> build_solr_schema
> clear_index
> haystack_info
> rebuild_index
> update_index
>
> [hyperkitty]
> attachments_to_file
> hyperkitty_import
> hyperkitty_warm_up_cache
> mailman_sync
> update_index_one_list
>
> [postorius]
> mmclient
> reset_passwords
>
> [rest_framework]
> generateschema
>
> [sessions]
> clearsessions
>
> [staticfiles]
> collectstatic
> findstatic
> runserver
> ```
>
>
> --
> Mark Sapiro <mark(a)msapiro.net> The highway is for gamblers,
> San Francisco Bay Area, California better use your sense - B. Dylan
>
> _______________________________________________
> Mailman-users mailing list -- mailman-users(a)mailman3.org
> To unsubscribe send an email to mailman-users-leave(a)mailman3.org
> https://lists.mailman3.org/mailman3/lists/mailman-users.mailman3.org/
> Archived at:
> https://lists.mailman3.org/archives/list/mailman-users@mailman3.org/message…
>
> This message sent to helio(a)loureiro.eng.br
>
2 years, 4 months
Re: Database permission problem?
by Bill Oliver
On Tue, 2024-10-15 at 17:13 -0700, Mark Sapiro wrote:
> On 10/15/24 15:24, Bill Oliver wrote:
> >
> > Yeah, I saw that, too. The double db files are created by
> > postmap. I
> > haven't worried about it too much yet, since the permissions are
> > the
> > same. I don't know why postmap does this, but it's next on my
> > list of
> > things to fix.
>
>
> You should not be running postmap manually and never on a *.db file
> in
> any case. Mailman should be creating postfix_domains, postfix_lmtp
> and
> postfix_vmap and calling postmap on those to create the .db files.
>
> > In my main.cf postfix_lmtp is mentioned four times:
> >
> > virtual_mailbox_maps =
> > proxy:mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf,
> >
> > proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_map
> > s.cf
> > #added 20241009 for mailman
> > hash:/opt/mailman/mm/var/data/postfix_lmtp ${dovecot}
> >
> > virtual_alias_maps =
> > proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf,
> >
> > proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf,
> >
> > proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_catchall_ma
> > ps.c
> > f
> > #added 20241009 for mailman
> > hash:/opt/mailman/mm/var/data/postfix_vmap
> >
> > #Mailman transport stuff
> > transport_maps =
> > hash:/opt/mailman/mm/var/data/postfix_lmtp
> > local_recipient_maps =
> > hash:/opt/mailman/mm/var/data/postfix_lmtp ${dovecot}
>
>
> Are you adding ${dovecot} to the local_recipient_maps and
> virtual_mailbox_maps mailman entries or was that there before?
Thanks. The reason I created them by hand is that they are not being
created automatically it seemed. If I remove them and restart things, I
get the following errors in /var/log/mail.err:
2024-10-15T12:43:31.060478-04:00 mail postfix/smtpd[961837]: error:
open database /opt/mailman/mm/var/data/postfix_domains.db: No such file
or directory
2024-10-15T12:43:31.060874-04:00 mail postfix/smtpd[961837]: error:
open database /opt/mailman/mm/var/data/postfix_lmtp.db: No such file or
directory
2024-10-15T12:43:31.069450-04:00 mail postfix/smtpd[961837]: error:
open database /opt/mailman/mm/var/data/postfix_vmap.db: No such file or
directory
However.... I just looked at the /opt/mailman/mm/var/data directory and
the (single) db files are now there, and that error occurs only once.
So, I probably over-reacted to it.
Unfortunately, I'm back to the permission declined error:
2024-10-15T22:31:31.973125-04:00 mail postfix/virtual[3497]: error:
open database /opt/mailman/mm/var/data/postfix_lmtp.db: Permission
denied
As far as the addition of ${dovecot} goes, I did it myself because of
the instructions at:
https://docs.mailman3.org/projects/mailman/en/latest/src/mailman/docs/mta.h…
Dovecot is having a hard time authenticating mailinglist users. I
figured that problem arose because it can't use any of the mailman .db
files, but I don't know. In any case, a dovecot error message that
happens when a user (who has an account on the local machine) sends
mail to the mailing list includes:
2024-10-15T21:50:45.231465-04:00 mail dovecot: auth-worker(5669):
Debug: conn unix:auth-worker (pid=3690,uid=111): auth-worker<1>:
pam(oliver(a)billoblog.com,129.222.252.225): lookup service=dovecot
2024-10-15T21:50:45.234036-04:00 mail dovecot: auth-worker(5669):
Debug: conn unix:auth-worker (pid=3690,uid=111): auth-worker<1>:
pam(oliver(a)billoblog.com,129.222.252.225): #1/1 style=1 msg=Password:
2024-10-15T21:50:46.716360-04:00 mail dovecot: auth-worker(5669): conn
unix:auth-worker (pid=3690,uid=111): auth-worker<1>:
pam(oliver(a)billoblog.com,129.222.252.225): pam_authenticate() failed:
Authentication failure (Password mismatch?) (given password: XXXXXXX)
2024-10-15T21:50:46.716497-04:00 mail dovecot: auth-worker(5669):
Debug: conn unix:auth-worker (pid=3690,uid=111): auth-worker<1>:
pam(oliver(a)billoblog.com,129.222.252.225): Finished passdb lookup
2024-10-15T21:50:46.716562-04:00 mail dovecot: auth-worker(5669):
Debug: conn unix:auth-worker (pid=3690,uid=111): auth-worker<1>:
Finished: password_mismatch
It should be noted that mail works fine for that user, and this error
arises *only* when mail is sent to the mailinglist address. Dovecot
does not complain if I send mail elsewhere. Mail is received and
delivered to and from this address without a problem.
The other thing I did was add an alias domain when I set up the domain
in postorius, again because it seemed from reading the instructions
that this was advisable on a server with multiple virtual domains.
Thanks.
1 year, 6 months
Re: Disable Sign-up per domain
by Mark
On 2025-08-01 01:37, Mark Sapiro wrote:
>> raise self.model.DoesNotExist(
>> django.contrib.sites.models.Site.DoesNotExist: Site matching query
>> does not exist.
> That error will occur when settings.py contains
>
> SITE_ID = 0
>
> and the host in the http request is not one of the hosts in the
> django_site table in the database or in Sites in the Django admin web
> UI.
> Is that possibly the case here?
The SITE_ID and database table check okay. The SITE_ID is supposed to be
"0"? No?
SITE_ID
Test server - settings.py: SITE_ID = 0
Prod server - settings.py: SITE_ID = 0
HTTP_HOST
Test server DB - mailmanweb.django_site table: domain and name fields OK
Prod server DB - mailmanweb.django_site table: domain and name fields
OK
And the hosts are displayed in Sites in the admin UI.
I also checked the ALLOWED_HOSTS in the Test and Prod servers. Both
have:
...
"localhost",
"127.0.0.1",
"<IP4 ADDRESS OF HOST>",
"<MY.DOMAIN.COM>"
"<OTHER.DOMAINNAME.COM>",
...
> Is there a complete traceback preceding the log snippet you report. If
> so, what is it?
The traceback does suggest that the SITE does not exist...
======================= TRACEBACK =====================
Traceback (most recent call last):
File
"/opt/mailman/venv/lib/python3.11/site-packages/django/contrib/sites/models.py",
line 39, in _get_site_by_request
SITE_CACHE[host] = self.get(domain__iexact=host)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/opt/mailman/venv/lib/python3.11/site-packages/django/db/models/manager.py",
line 87, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/opt/mailman/venv/lib/python3.11/site-packages/django/db/models/query.py",
line 637, in get
raise self.model.DoesNotExist(
django.contrib.sites.models.Site.DoesNotExist: Site matching query does
not exist.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File
"/opt/mailman/venv/lib/python3.11/site-packages/django/core/handlers/exception.py",
line 55, in inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^
File
"/opt/mailman/venv/lib/python3.11/site-packages/django/core/handlers/base.py",
line 197, in _get_response
response = wrapped_callback(request, *callback_args,
**callback_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/opt/mailman/venv/lib/python3.11/site-packages/postorius/views/list.py",
line 1158, in list_index
return render(
^^^^^^^
File
"/opt/mailman/venv/lib/python3.11/site-packages/django/shortcuts.py",
line 24, in render
content = loader.render_to_string(template_name, context, request,
using=using)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/opt/mailman/venv/lib/python3.11/site-packages/django/template/loader.py",
line 62, in render_to_string
return template.render(context, request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/opt/mailman/venv/lib/python3.11/site-packages/django/template/backends/django.py",
line 61, in render
return self.template.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/opt/mailman/venv/lib/python3.11/site-packages/django/template/base.py",
line 173, in render
with context.bind_template(self):
File "/usr/lib/python3.11/contextlib.py", line 137, in __enter__
return next(self.gen)
^^^^^^^^^^^^^^
File
"/opt/mailman/venv/lib/python3.11/site-packages/django/template/context.py",
line 254, in bind_template
updates.update(processor(self.request))
^^^^^^^^^^^^^^^^^^^^^^^
File
"/opt/mailman/venv/lib/python3.11/site-packages/django_mailman3/context_processors.py",
line 32, in common
context["site_name"] = get_current_site(request).name
^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/opt/mailman/venv/lib/python3.11/site-packages/django/contrib/sites/shortcuts.py",
line 16, in get_current_site
return Site.objects.get_current(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/opt/mailman/venv/lib/python3.11/site-packages/django/contrib/sites/models.py",
line 61, in get_current
return self._get_site_by_request(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/opt/mailman/venv/lib/python3.11/site-packages/django/contrib/sites/models.py",
line 45, in _get_site_by_request
SITE_CACHE[domain] = self.get(domain__iexact=domain)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/opt/mailman/venv/lib/python3.11/site-packages/django/db/models/manager.py",
line 87, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/opt/mailman/venv/lib/python3.11/site-packages/django/db/models/query.py",
line 637, in get
raise self.model.DoesNotExist(
django.contrib.sites.models.Site.DoesNotExist: Site matching query does
not exist.
ERROR 2025-08-01 05:21:46,176 2030595 django.request Internal Server
Error: /owa/auth/logon.aspx
ERROR 2025-08-01 05:21:46,176 2030595 django.request Internal Server
Error: /owa/auth/logon.aspx
============= END TRACEBACK =================
>> ... -- "whatever is proxying to Django setting the appropriate
>> HTTP_HOST header." -- which I don't understand.
> This is in the configuration of the web server. It should be
> configured to pass the host of the incoming request to the proxy
> target in the HTTP_HOST header. In nginx this is `proxy_set_header
> Host $host;`. In apache it is `ProxyPreserveHost On`, but again the
> change to user_adapter shouldn't affect this.
>
That all looks good for both the Prod and Test servers.
...
location /static/ {
alias /opt/mailman/web/static/;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
...
8 months, 4 weeks
Re: Issues with Mail delivery after Mailman 3 installation
by Stephen J. Turnbull
Chihurumnaya Ibiam via Mailman-users writes:
> On Wed, Feb 4, 2026 at 9:06 PM Stephen J. Turnbull <steve(a)turnbull.jp>
> wrote:
>
> > Chihurumnaya Ibiam via Mailman-users writes:
> > > systemctl shows the service is still active,
> > The fact that there is a systemd service implies that dovecot
> > will be running by default unless it is disabled.
> There's no service file for dovecot, I didn't create one.
As far as I know, if systemd knows about a service, there's a control
file somewhere. systemd will create a unit from an rc file in
/etc/rcN.d if there is one. (I was perfectly happy with SysV init,
but I guess systemd makes hyperscalars happy.) I don't know if
"systemctl disable" works on those.
> I configured mailbox transport because that was how I was able to get lmtp
> to run on port 24,
Something like that would be necessary for Dovecot, which I believe
can be configured to automatically create a mailbox for any address.
It is not necessary for Mailman, which tells Postfix how to deliver to
Mailman lists in the postfix_lmtp table. You can find that in
/opt/mailman/mm/var/data, if you followed the virtualenv installation
to the letter.
It's problematic for Mailman because that means that *all* local mail
will be delivered to Mailman, which will reject it if it's not
list-related.
I'm not sure this is why the confirmation mails are getting rejected,
but at a guess, for some classes of mail Postfix will first try the
whole address, and if that fails to route, it will remove the
extension (starting with "+"), and try again. Perhaps it does NOT do
that for the mailbox_transport.
> there wasn't any service before that and the documentation
> <https://docs.mailman3.org/projects/mailman/en/latest/src/mailman/docs/mta.h…>
> for setting up a mail server mentions postfix delivering
> by default over port 24.
What it says is this:
Postfix will deliver via LMTP over port 24 by default, however if
you are not running Mailman as root, you’ll need to change this to
a higher port number, as shown above.
Are you running Mailman as root? If so, stop it, change lmtp_port
back to 8024 in mailman.cfg, and stop and start Mailman to regenerate
the postfix_lmtp.db. There's no need for running as root unless you
have an MTA that is hard-coded to think that 24 is the one and only
lmtp port handed down from Mount Olympus. Postfix knows better.
Furthermore, you should NOT run mailman as root if there's any
alternative. Mailman occasionally crashes for various reasons (I've
never seen it take Python down, but then, if there were an exploit, I
wouldn't), and is not securely authenticated (I mean, it's reasonably
secure, but it is just a password, and once you get in to Mailman
core, you're the superuser for Mailman) and if there *is* an exploit
and Mailman is running as root, you've got system root, too.
Don't run Mailman as root. Please.
> Disabling this means there's no lmtp to be used by postfix, except I'm
> missing something.
Yes, you're missing something. Postfix is always able to speak LMTP,
and is very flexible about when to do so. If you followed the virtualenv
installation to the letter, you have
transport_maps = hash:/opt/mailman/mm/var/data/postfix_lmtp
in main.cf (perhaps there's other maps there), and in that file you
have lines that end in "lmtp:[127.0.0.1]:24", which tell Postfix
"connect to IP address 127.0.0.1, port 24, and speak LMTP to that
connection." If you change lmtp_port to 8024 and restart Mailman as
suggested, all those lines will change to "lmtp:[127.0.0.1]:8024" and
Postfix will be happy to deliver to Mailman that way without being root.
> I set the port number for lmtp to be 24, and that's what I used, I'm not
> sure if Mailman sets up lmtp itself,
> if it does then I'll have to remove the config for that.
>
> I've stopped dovecot after our conversation so it's no longer running, the
> only way the port is open is through the
> config I set in postfix for mailbox_transport.
That should get it working, except that with mailbox_transport set
there's a good chance that Mailman functions that use "+" extensions
will mess up as described above. Those functions are confirmations
and I think VERP probes.
> There's just one active user, which is me, and I also have root access.
> I setup authentication for postfix because I'm used to setting it up that
> way, this was a force of habit.
> I assumed postfix would run just fine if I set postfix up the way I usually
> set it up.
It might. But "Internet Mail" is another name for Dante's Third Circle
of Hell. (You must have committed a horrible felony to be sentenced
to administer an Internet mail host. :-D That's just a joke, it
sounds to me like your "usual setup" is quite solid and secure.)
Anyway, any deviation from the setup described in virtualenv.html is a
chance for everything to go wrong. "What I usually do" is just not
deep enough knowledge if you're working with a new mail application
with complex routing needs.
> > What does "lsof -i @127.0.0.1 -i '@[::1]' | grep 24" output?
> python3 1592922 mailman 27u IPv4 177685024 0t0 TCP localhost:8001 (LISTEN)
> python3 1592949 mailman 27u IPv4 177685024 0t0 TCP localhost:8001 (LISTEN)
> python3 1592950 mailman 27u IPv4 177685024 0t0 TCP localhost:8001 (LISTEN)
The above are Mailman (actually, a gunicorn application) listening for
connections to its REST API. These are HTTP listeners used by
Postorius and HyperKitty (I guess those aren't running?), not for email.
> postgres 3568035 postgres 5u IPv6 160224851 0t0 TCP localhost:postgresql (LISTEN)
> postgres 3568035 postgres 6u IPv4 160224852 0t0 TCP localhost:postgresql (LISTEN)
These are PostgreSQL listening for database connections.
> python3 1592924 mailman 22u IPv6 177685051 0t0 TCP localhost:48638->localhost:postgresql (ESTABLISHED)
This is Mailman talking to Postfix.
> postgres 1592954 postgres 9u IPv6 177686124 0t0 TCP localhost:postgresql->localhost:48498 (ESTABLISHED)
> postgres 1592912 postgres 8u IPv6 160224857 0t0 UDP localhost:36787->localhost:36787
+ 21 more copies of the above, differing only in the PID. Don't know
what's going on with those, not a PostgreSQL wizard. I probably
should have specified TCP in the lsof command, UDP applications are
either trivial or they are black magic.
It appears that *nothing* is listening on or connected to port 24.
I'm not sure how that works. I'm guessing that when mail was getting
to Mailman, Mailman had opened port 24 and Dovecot was cut out of the
loop (maybe check logs for Dovecot complaining it couldn't bind to
port 24?)
> > > [mta] lmtp_host: *.*.*.*
> >
> > That should be 127.0.0.1. Mailman should not be listening on network
> > interfaces other than the loopback (localhost).
>
> Yes, it is.
OK
> > > [mta] lmtp_port: 24
> >
> > This can't work if Dovecot is configured to use the same port, as is
> > Dovecot's default.
> I've stopped the service.
OK
> > > [mta] outgoing: mailman.mta.deliver.deliver
> > > [mta] smtp_host: 127.0.0.1
> > > [mta] smtp_port: 25
> >
> > Those are normal.
> >
> > > [mta] smtp_pass: **************
> > > [mta] smtp_user: mailman
> >
> > This is going to cause Mailman to try to authenticate to Postfix.
> > That's OK if it's what you want and Postfix / saslauthd has been
> > properly configured to accept Mailman's credentials. Otherwise,
> > they must be left empty to disable authentication.
> Okay.
> > > The Message-ID being the way it is doesn't seem like a
> > > configuration issue, if it is then how do I look into it?
> >
> > Probably you don't have the full hostname in Postfix's myorigin or
> > myhostname parameter.
>
> I do have the full hostname there, I also have it in /etc/mailname.
I don't understand it then. Perhaps the mail composition client is
providing the Message-ID.
> > If not, I would guess that's a spammer who is somehow spoofing
> > the PTR record.
> The log entry before that warned of the same, they're definitely a spammer.
> Relay access is denied though, so no mails are going through.
OK.
> No, I mean smtps.
Same problem except the port that Mailman is *not* using is 465.
> > I don't think permit_auth_destination does what you think it does.
> > Here's the Postfix doc:
> >
> > permit_auth_destination
> > Permit the request when one of the following is true:
> >
> > - Postfix is a mail forwarder: the resolved RCPT TO domain
> > matches $relay_domains or a subdomain thereof, and the address
> > contains no sender-specified routing (user@elsewhere@domain),
> > - Postfix is the final destination: the resolved RCPT TO domain
> > matches $mydestination, $inet_interfaces, $proxy_interfaces,
> > $virtual_alias_domains, or $virtual_mailbox_domains, and the
> > address contains no sender-specified routing
> > (user@elsewhere@domain).
> >
>
> I did read the documentation before adding it, I definitely misunderstood
> what it meant, and after looking at the old
> documentation, it makes sense not to add it.
>
> Could you help me understand what the above means?
I gotta run now, I'll come back to it later. You're probably asleep,
anyway. :-)
--
GNU Mailman consultant (installation, migration, customization)
Sirius Open Source https://www.siriusopensource.com/
Software systems consulting in Europe, North America, and Japan
2 months, 3 weeks
Re: config incoming email in my domain cpanel
by Rafael Mora
El jue., 3 ago. 2017 a las 15:49, tlhackque via Mailman-users (<
mailman-users(a)mailman3.org>) escribió:
> I think you're confused.
>
> You already have mail.labbrands.com set up as the MX record for
> labbrands.com. And it has an A record with the same address as your
> webserver.
>
I'm working with the hostgator mailserver, we are not running a local
mailserver.
As suggested I added an A record like this:
[image: image.png]
Is it correct? is it redirecting to my Ip so I can redirect it to my
postfix/mm3 server?
>
> So if you're getting e-mail on that domain, there's another e-mail
> server running on that IP address. You can't have 2 servers on port
> 25. In that case, as has been noted before, you'll need to setup a
> relay in that server, not a firewall redirect. Depending on your MTA,
> you would need to relay to your internal server. And make sure your
> firewall setup allows your MTA to do this.
>
> We can see it's EXIM:
>
> telnet mail.labbrands.com 25
> Trying 192.185.51.89...
> Connected to mail.labbrands.com (192.185.51.89).
> Escape character is '^]'.
> help
> 220-gator4137.hostgator.com ESMTP Exim 4.87 #1 Thu, 03 Aug 2017 15:47:48
> -0500
> 220-We do not authorize the use of this system to transport unsolicited,
> 220 and/or bulk e-mail.
> 214-Commands supported:
> 214 AUTH STARTTLS HELO EHLO MAIL RCPT DATA NOOP QUIT RSET HELP
> quit
> 221 gator4137.hostgator.com closing connection
> Connection closed by foreign host.
>
> Or, consolidate all your e-mail to one server - which is a lot easier to
> manage unless you have a really big operation. Postfix is probably the
> right choice, but requires more setup.
>
> Although Mailman3 configuration is not well documented (as you've
> discovered), you may want to get help from someone with more general
> network and mail experience. You're now into territory that is, as
> Simon indicated, not Mailman-specific.
>
> On 03-Aug-17 16:28, Rafael Mora wrote:
> > El jue., 3 ago. 2017 a las 15:26, Mark Sapiro (<mark(a)msapiro.net>)
> escribió:
> >
> >> On 08/03/2017 01:22 PM, Rafael Mora wrote:
> >>> El jue., 3 ago. 2017 a las 15:18, Mark Sapiro (<mark(a)msapiro.net>)
> >> escribió:
> >>>> You need to forward port 25 for SMTP mail delivery and if you want the
> >>>> web UI (Postorius and HyperKitty) accessible from the outside, port 80
> >>>> for http and/or port 443 for https
> >>>> <
> >>>>
> >>
> https://www.iana.org/assignments/service-names-port-numbers/service-names-p…
> >>>>> .
> >>> I mean for incoming mail redirected from my hostgator hosting, because
> >> when
> >>> I suscribe an email address MM3 sends a confirmation email, so I have
> to
> >>> reply to be suscribed to the list.
> >>
> >> As I said, for mail delivery you need to forward port 25 to the Mailman
> >> server.
> >>
> > Ok so I'll redirect in my zentyal firewall the port 25 to my local
> centos7
> > with postfix and MM3 with IP 192.168.1.42. Thanks Mark.
> >
> >
> >>
> >> --
> >> Mark Sapiro <mark(a)msapiro.net> The highway is for gamblers,
> >> San Francisco Bay Area, California better use your sense - B. Dylan
> >> _______________________________________________
> >> Mailman-users mailing list
> >> mailman-users(a)mailman3.org
> >> https://lists.mailman3.org/mailman3/lists/mailman-users.mailman3.org/
> >>
>
> --
> This communication may not represent my employer's views,
> if any, on the matters discussed.
>
> _______________________________________________
> Mailman-users mailing list
> mailman-users(a)mailman3.org
> https://lists.mailman3.org/mailman3/lists/mailman-users.mailman3.org/
>
--
Atentamente / Best Regards
Ing. Rafael Mora
8 years, 8 months
Re: Docker Mailman3 installation frustration
by Abhilash Raj
Hi,
On Wed, Jul 12, 2017, at 02:04 PM, ccsmith(a)cetsi.com wrote:
<snip>
> Running "sudo docker exec -it mailman-web cat
> ../mailman-web-data/logs/mailmanweb.log" shows me:
>
> ERROR 2017-07-12 20:34:25,073 25 django.request Internal Server Error: /accounts/login/
> Traceback (most recent call last):
> File "/usr/local/lib/python2.7/site-packages/django/core/handlers/exception.py", line 39, in inner
> response = get_response(request)
> ... more stuff ...
> File "/usr/local/lib/python2.7/smtplib.py", line 747, in sendmail
> raise SMTPRecipientsRefused(senderrs)
> SMTPRecipientsRefused: {u'pacetechadmin(a)cetsi.com': (451, '4.3.0 <pacetechadmin(a)cetsi.com>: Temporary lookup failure')}
This is mostly because you didn't setup your Django instance to send
emails i.e. SMTP settings. When you try to login/sign up from the web
interface, it needs to verify your email account and fails with 500
error because SMTP being not configured.
> On the Docker host (ubuntuServer2), /var/log/mail.log shows:
> Jul 12 13:48:53 ubuntuServer2 postfix/smtpd[19931]: error: open /opt/mailman/core/var/data/postfix_domains: No such file or directory
> Jul 12 13:48:53 ubuntuServer2 postfix/smtpd[19931]: error: open /opt/mailman/core/var/data/postfix_lmtp: No such file or directory
> Jul 12 13:48:53 ubuntuServer2 postfix/smtpd[19931]: connect from unknown[172.19.199.3]
> Jul 12 13:48:53 ubuntuServer2 postfix/trivial-rewrite[19843]: warning: regexp:/opt/mailman/core/var/data/postfix_domains is unavailable. open /opt/mailman/core/var/data/postfix_domains: No such file or directory
> Jul 12 13:48:53 ubuntuServer2 postfix/trivial-rewrite[19843]: warning: relay_domains: regexp:/opt/mailman/core/var/data/postfix_domains: table lookup problem
> Jul 12 13:48:53 ubuntuServer2 postfix/trivial-rewrite[19843]: warning: relay_domains lookup failure
> Jul 12 13:48:53 ubuntuServer2 postfix/trivial-rewrite[19843]: warning: regexp:/opt/mailman/core/var/data/postfix_domains is unavailable. open /opt/mailman/core/var/data/postfix_domains: No such file or directory
> Jul 12 13:48:53 ubuntuServer2 postfix/trivial-rewrite[19843]: warning: relay_domains: regexp:/opt/mailman/core/var/data/postfix_domains: table lookup problem
> Jul 12 13:48:53 ubuntuServer2 postfix/trivial-rewrite[19843]: warning: relay_domains lookup failure
> Jul 12 13:48:53 ubuntuServer2 postfix/smtpd[19931]: NOQUEUE: reject: RCPT from unknown[172.19.199.3]: 451 4.3.0 <pacetechadmin(a)cetsi.com>: Temporary lookup failure; from=<postorius(a)localhost.local> to=<pacetechadmin(a)cetsi.com> proto=ESMTP helo=<mailman-web>
> Jul 12 13:48:54 ubuntuServer2 postfix/smtpd[19932]: error: open /opt/mailman/core/var/data/postfix_domains: No such file or directory
> Jul 12 13:48:54 ubuntuServer2 postfix/smtpd[19932]: error: open /opt/mailman/core/var/data/postfix_lmtp: No such file or directory
> Jul 12 13:48:54 ubuntuServer2 postfix/smtpd[19932]: connect from unknown[172.19.199.3]
> Jul 12 13:48:54 ubuntuServer2 postfix/trivial-rewrite[19843]: warning: regexp:/opt/mailman/core/var/data/postfix_domains is unavailable. open /opt/mailman/core/var/data/postfix_domains: No such file or directory
> Jul 12 13:48:54 ubuntuServer2 postfix/trivial-rewrite[19843]: warning: relay_domains: regexp:/opt/mailman/core/var/data/postfix_domains: table lookup problem
> Jul 12 13:48:54 ubuntuServer2 postfix/trivial-rewrite[19843]: warning: relay_domains lookup failure
> Jul 12 13:48:54 ubuntuServer2 postfix/trivial-rewrite[19843]: warning: regexp:/opt/mailman/core/var/data/postfix_lmtp is unavailable. open /opt/mailman/core/var/data/postfix_lmtp: No such file or directory
> Jul 12 13:48:54 ubuntuServer2 postfix/trivial-rewrite[19843]: warning: regexp:/opt/mailman/core/var/data/postfix_lmtp lookup error for "root@localhost"
> Jul 12 13:48:54 ubuntuServer2 postfix/trivial-rewrite[19843]: warning: transport_maps lookup failure
> Jul 12 13:48:54 ubuntuServer2 postfix/smtpd[19932]: NOQUEUE: reject: RCPT from unknown[172.19.199.3]: 451 4.3.0 <root@localhost>: Temporary lookup failure; from=<root(a)localhost.local> to=<root@localhost> proto=ESMTP helo=<mailman-web>
> Jul 12 13:48:54 ubuntuServer2 postfix/smtpd[19932]: disconnect from unknown[172.19.199.3] ehlo=1 mail=1 rcpt=0/1 rset=1 quit=1 commands=4/5
> Jul 12 13:48:54 ubuntuServer2 postfix/smtpd[19931]: lost connection after RSET from unknown[172.19.199.3]
> Jul 12 13:48:54 ubuntuServer2 postfix/smtpd[19931]: disconnect from unknown[172.19.199.3] ehlo=1 mail=1 rcpt=0/1 rset=1 commands=3/4
>
> And /var/log/mail.err is filling up with:
> Jul 12 13:48:53 ubuntuServer2 postfix/smtpd[19931]: error: open /opt/mailman/core/var/data/postfix_domains: No such file or directory
> Jul 12 13:48:53 ubuntuServer2 postfix/smtpd[19931]: error: open /opt/mailman/core/var/data/postfix_lmtp: No such file or directory
> Jul 12 13:48:54 ubuntuServer2 postfix/smtpd[19932]: error: open /opt/mailman/core/var/data/postfix_domains: No such file or directory
> Jul 12 13:48:54 ubuntuServer2 postfix/smtpd[19932]: error: open /opt/mailman/core/var/data/postfix_lmtp: No such file or directory
This is, as mentioned in the Issue that Danil linked to, about postfix
complaining about non-existent transport maps.
It will probably make sense to create those files, even empty, when the
containers startup!
Hope that helps!
--
Abhilash Raj
maxking(a)asynchronous.in
8 years, 9 months
Re: Mailman 3 Status Update Please?
by Barry Warsaw
On Jul 22, 2017, at 06:58, tlhackque via Mailman-users <mailman-users(a)mailman3.org> wrote:
>
> On 21-Jul-17 22:58, Barry Warsaw wrote:
>>
>> One big project that I’d love to see gain more traction is Lemme, our authenticating REST proxy. We just haven’t had much collective resources to spend working on it.
>>
>> https://gitlab.com/mailman/lemme
>
> The architectural problem with a separate proxy that provides separation
> of privilege is that the proxy has to be kept in sync with the core -
This can be true, as is the case for example in mailmanclient. I think that’s different than the lemme case though because mmclient is a language binding to a REST API, so it needs to know the details of the API in order to provide a high-fidelity binding. This could potentially be mitigated if we had a static representation of the API, and there have been discussions of that elsewhere, so let’s not dive too deeply into that discussion here.
Where I think lemme is different is that it would be a more pure HTTP command forwarding proxy with a bit of preprocessing. It wouldn’t need to know the details of the REST API and wouldn’t need to be explicitly kept in sync.
The general approach we hashed out a few Pycons ago is outlined here: https://gitlab.com/mailman/lemme/blob/master/OUTLINE.rst
> In addition, as the recent issues indicate, the REST API already has
> scaling problems - adding a proxy in the path will exacerbate those.
Yes, the proxy will not be very fast, but it’s also targeting a very different audience.
The current REST API, what I call the “administrative” API needs to be fast (and I’m confident we can make improvements to the existing implementation) because it’s there to serve Postorius, HyperKitty, and any other custom, tightly integrated front-ends. It provides full access to the API with no authorization because it trusts those front-ends implicitly, and those front-ends need the ability to perform any necessary action.
Lemme must fundamentally *not* trust its clients. Authentication is only the first part of its paranoia; it must also authorize the authenticated user and determine whether they have permissions to perform the requested action. It’s the authorization part that makes this a “big project” to me.
> Either way, the major work is (or should be) authorization tests in the
> core, with a touch of mapping an authenticated user to her(his)
> capabilities (for a list) in the database. Not a s"big" separate project.
I disagree about the bigness, but I can be convinced with code. :)
The core has no authorization or permission information built-in. It does have a user database, but I’ve always considered that to be tightly focused on the data needed to determine posting permissions, not access to the REST API. We also don’t have a model for how users map to API permissions. We’ve always recommended that the admin API be exposed only on trusted IPs (highly recommending localhost), but a proxy has to be exposed on the public internet for it to be useful. That, and because the admin API is default-open and the proxy must be default-closed, we want to segregate any possible vulnerabilities into an optional component. Not every site will want to allow their list operations to be scriptable.
To me, this all points to a separate proxy, developed as an official subproject. There we can experiment with permission models to find what works best and is the most understandable. We can allow others to experiment as well, and sites can opt into or out of running the proxy, or even the official proxy. Any vulnerabilities in the proxy can be fixed quickly, and rolled out on a different release schedule than Core.
Now, we’re careful, I think the bulk of lemme could be written with an eye toward some future integration with Core, although I would strongly recommend running it as a separate HTTP server than the admin API. That way, we can experiment with and develop lemme at its own pace, and once it stabilizes, we could consider bringing it in as a Core feature.
Cheers,
-Barry
8 years, 9 months
Re: Hyperkitty
by Massimiliano Paragnani
SOLVED!
I edited /etc/mailman3/mailman3-web.py adding in MAILMAN_ARCHIVER_FROM =
the ip of the server and finally starts to work
Il Ven 27 Gen 2023, 18:52 Massimiliano Paragnani <max.paragnani(a)gmail.com>
ha scritto:
> I set up the mailman3 services and lists, and we can send mail to the
> list successfully. However in the Archive section I couldn't see
> anything.
> My configuration: ubuntu, milman core 3.2.2, postresql, postorius 1.2.4,
> hyperkitty 1.3.2
>
> This is my mailman conf result:
>
> [antispam] header_checks:
> [antispam] jump_chain: hold
> [archiver.mail_archive] class: mailman.archiving.mailarchive.MailArchive
> [archiver.mail_archive] clobber_date: maybe
> [archiver.mail_archive] clobber_skew: 1d
> [archiver.mail_archive] configuration: python:mailman.config.mail_archive
> [archiver.mail_archive] enable: no
> [archiver.mhonarc] class: mailman.archiving.mhonarc.MHonArc
> [archiver.mhonarc] clobber_date: maybe
> [archiver.mhonarc] clobber_skew: 1d
> [archiver.mhonarc] configuration: python:mailman.config.mhonarc
> [archiver.mhonarc] enable: no
> [archiver.prototype] class: mailman.archiving.prototype.Prototype
> [archiver.prototype] clobber_date: maybe
> [archiver.prototype] clobber_skew: 1d
> [archiver.prototype] configuration: changeme
> [archiver.prototype] enable: no
> [bounces] register_bounces_every: 15m
> [database] class: mailman.database.postgresql.PostgreSQLDatabase
> [database] debug: no
> [database] url: postgres://mailman3:--------------@localhost/mailman3
> [devmode] enabled: no
> [devmode] recipient:
> [devmode] testing: no
> [devmode] wait: 60s
> [digests] mime_digest_keep_headers:
> Date From To Cc Subject Message-ID Keywords
> In-Reply-To References Content-Type MIME-Version
> Content-Transfer-Encoding Precedence Reply-To
> Message List-Post
> [digests] plain_digest_keep_headers:
> Message Date From
> Subject To Cc
> Message-ID Keywords
> Content-Type
> [dmarc] cache_lifetime: 7d
> [dmarc] org_domain_data_url:
> https://publicsuffix.org/list/public_suffix_list.dat
> [dmarc] resolver_lifetime: 5s
> [dmarc] resolver_timeout: 3s
> [language.ar] charset: utf-8
> [language.ar] description: Arabic
> [language.ar] enabled: yes
> [language.ast] charset: iso-8859-1
> [language.ast] description: Asturian
> [language.ast] enabled: yes
> [language.ca] charset: utf-8
> [language.ca] description: Catalan
> [language.ca] enabled: yes
> [language.cs] charset: iso-8859-2
> [language.cs] description: Czech
> [language.cs] enabled: yes
> [language.da] charset: iso-8859-1
> [language.da] description: Danish
> [language.da] enabled: yes
> [language.de] charset: utf-8
> [language.de] description: German
> [language.de] enabled: yes
> [language.el] charset: iso-8859-7
> [language.el] description: Greek
> [language.el] enabled: yes
> [language.es] charset: iso-8859-1
> [language.es] description: Spanish
> [language.es] enabled: yes
> [language.et] charset: iso-8859-15
> [language.et] description: Estonian
> [language.et] enabled: yes
> [language.eu] charset: iso-8859-15
> [language.eu] description: Euskara
> [language.eu] enabled: yes
> [language.fi] charset: iso-8859-1
> [language.fi] description: Finnish
> [language.fi] enabled: yes
> [language.fr] charset: iso-8859-1
> [language.fr] description: French
> [language.fr] enabled: yes
> [language.gl] charset: utf-8
> [language.gl] description: Galician
> [language.gl] enabled: yes
> [language.he] charset: utf-8
> [language.he] description: Hebrew
> [language.he] enabled: yes
> [language.hr] charset: iso-8859-2
> [language.hr] description: Croatian
> [language.hr] enabled: yes
> [language.hu] charset: iso-8859-2
> [language.hu] description: Hungarian
> [language.hu] enabled: yes
> [language.ia] charset: iso-8859-15
> [language.ia] description: Interlingua
> [language.ia] enabled: yes
> [language.it] charset: iso-8859-1
> [language.it] description: Italian
> [language.it] enabled: yes
> [language.ja] charset: euc-jp
> [language.ja] description: Japanese
> [language.ja] enabled: yes
> [language.ko] charset: euc-kr
> [language.ko] description: Korean
> [language.ko] enabled: yes
> [language.lt] charset: iso-8859-13
> [language.lt] description: Lithuanian
> [language.lt] enabled: yes
> [language.nl] charset: iso-8859-1
> [language.nl] description: Dutch
> [language.nl] enabled: yes
> [language.no] charset: iso-8859-1
> [language.no] description: Norwegian
> [language.no] enabled: yes
> [language.pl] charset: iso-8859-2
> [language.pl] description: Polish
> [language.pl] enabled: yes
> [language.pt] charset: iso-8859-1
> [language.pt] description: Protuguese
> [language.pt] enabled: yes
> [language.pt_BR] charset: iso-8859-1
> [language.pt_BR] description: Protuguese (Brazil)
> [language.pt_BR] enabled: yes
> [language.ro] charset: iso-8859-2
> [language.ro] description: Romanian
> [language.ro] enabled: yes
> [language.ru] charset: koi8-r
> [language.ru] description: Russian
> [language.ru] enabled: yes
> [language.sk] charset: utf-8
> [language.sk] description: Slovak
> [language.sk] enabled: yes
> [language.sl] charset: iso-8859-2
> [language.sl] description: Slovenian
> [language.sl] enabled: yes
> [language.sr] charset: utf-8
> [language.sr] description: Serbian
> [language.sr] enabled: yes
> [language.sv] charset: iso-8859-1
> [language.sv] description: Swedish
> [language.sv] enabled: yes
> [language.tr] charset: iso-8859-9
> [language.tr] description: Turkish
> [language.tr] enabled: yes
> [language.uk] charset: utf-8
> [language.uk] description: Ukrainian
> [language.uk] enabled: yes
> [language.vi] charset: utf-8
> [language.vi] description: Vietnamese
> [language.vi] enabled: yes
> [language.zh_CN] charset: utf-8
> [language.zh_CN] description: Chinese
> [language.zh_CN] enabled: yes
> [language.zh_TW] charset: utf-8
> [language.zh_TW] description: Chinese (Taiwan)
> [language.zh_TW] enabled: yes
> [logging.archiver] datefmt: %b %d %H:%M:%S %Y
> [logging.archiver] format: %(asctime)s (%(process)d) %(message)s
> [logging.archiver] level: info
> [logging.archiver] path: mailman.log
> [logging.archiver] propagate: no
> [logging.bounce] datefmt: %b %d %H:%M:%S %Y
> [logging.bounce] format: %(asctime)s (%(process)d) %(message)s
> [logging.bounce] level: info
> [logging.bounce] path: bounce.log
> [logging.bounce] propagate: no
> [logging.config] datefmt: %b %d %H:%M:%S %Y
> [logging.config] format: %(asctime)s (%(process)d) %(message)s
> [logging.config] level: info
> [logging.config] path: mailman.log
> [logging.config] propagate: no
> [logging.database] datefmt: %b %d %H:%M:%S %Y
> [logging.database] format: %(asctime)s (%(process)d) %(message)s
> [logging.database] level: warn
> [logging.database] path: mailman.log
> [logging.database] propagate: no
> [logging.debug] datefmt: %b %d %H:%M:%S %Y
> [logging.debug] format: %(asctime)s (%(process)d) %(message)s
> [logging.debug] level: info
> [logging.debug] path: debug.log
> [logging.debug] propagate: no
> [logging.error] datefmt: %b %d %H:%M:%S %Y
> [logging.error] format: %(asctime)s (%(process)d) %(message)s
> [logging.error] level: info
> [logging.error] path: mailman.log
> [logging.error] propagate: no
> [logging.fromusenet] datefmt: %b %d %H:%M:%S %Y
> [logging.fromusenet] format: %(asctime)s (%(process)d) %(message)s
> [logging.fromusenet] level: info
> [logging.fromusenet] path: mailman.log
> [logging.fromusenet] propagate: no
> [logging.http] datefmt: %b %d %H:%M:%S %Y
> [logging.http] format: %(asctime)s (%(process)d) %(message)s
> [logging.http] level: info
> [logging.http] path: mailman.log
> [logging.http] propagate: no
> [logging.locks] datefmt: %b %d %H:%M:%S %Y
> [logging.locks] format: %(asctime)s (%(process)d) %(message)s
> [logging.locks] level: info
> [logging.locks] path: mailman.log
> [logging.locks] propagate: no
> [logging.mischief] datefmt: %b %d %H:%M:%S %Y
> [logging.mischief] format: %(asctime)s (%(process)d) %(message)s
> [logging.mischief] level: info
> [logging.mischief] path: mailman.log
> [logging.mischief] propagate: no
> [logging.plugins] datefmt: %b %d %H:%M:%S %Y
> [logging.plugins] format: %(asctime)s (%(process)d) %(message)s
> [logging.plugins] level: info
> [logging.plugins] path: plugins.log
> [logging.plugins] propagate: no
> [logging.root] datefmt: %b %d %H:%M:%S %Y
> [logging.root] format: %(asctime)s (%(process)d) %(message)s
> [logging.root] level: info
> [logging.root] path: mailman.log
> [logging.root] propagate: no
> [logging.runner] datefmt: %b %d %H:%M:%S %Y
> [logging.runner] format: %(asctime)s (%(process)d) %(message)s
> [logging.runner] level: info
> [logging.runner] path: mailman.log
> [logging.runner] propagate: no
> [logging.smtp] datefmt: %b %d %H:%M:%S %Y
> [logging.smtp] every: $msgid smtp to $listname for $recip recips,
> completed in $time seconds
> [logging.smtp] failure: $msgid delivery to $recip failed with code
> $smtpcode, $smtpmsg
> [logging.smtp] format: %(asctime)s (%(process)d) %(message)s
> [logging.smtp] level: info
> [logging.smtp] path: smtp.log
> [logging.smtp] propagate: no
> [logging.smtp] refused: $msgid post to $listname from $sender, $size
> bytes, $refused failures
> [logging.smtp] success: $msgid post to $listname from $sender, $size bytes
> [logging.subscribe] datefmt: %b %d %H:%M:%S %Y
> [logging.subscribe] format: %(asctime)s (%(process)d) %(message)s
> [logging.subscribe] level: info
> [logging.subscribe] path: mailman.log
> [logging.subscribe] propagate: no
> [logging.vette] datefmt: %b %d %H:%M:%S %Y
> [logging.vette] format: %(asctime)s (%(process)d) %(message)s
> [logging.vette] level: info
> [logging.vette] path: mailman.log
> [logging.vette] propagate: no
> [mailman] cache_life: 7d
> [mailman] default_language: en
> [mailman] email_commands_max_lines: 10
> [mailman] filtered_messages_are_preservable: no
> [mailman] html_to_plain_text_command: /usr/bin/lynx -dump $filename
> [mailman] layout: debian
> [mailman] listname_chars: [-_.0-9a-z]
> [mailman] noreply_address: noreply
> [mailman] pending_request_life: 3d
> [mailman] post_hook:
> [mailman] pre_hook:
> [mailman] sender_headers: from from_ reply-to sender
> [mailman] site_owner: max.paragnani(a)gmail.com
> [mta] configuration: python:mailman.config.postfix
> [mta] delivery_retry_period: 5d
> [mta] incoming: mailman.mta.postfix.LMTP
> [mta] lmtp_host: 127.0.0.1
> [mta] lmtp_port: 8024
> [mta] max_autoresponses_per_day: 10
> [mta] max_delivery_threads: 0
> [mta] max_recipients: 500
> [mta] max_sessions_per_connection: 0
> [mta] outgoing: mailman.mta.deliver.deliver
> [mta] remove_dkim_headers: no
> [mta] smtp_host: localhost
> [mta] smtp_pass:
> [mta] smtp_port: 25
> [mta] smtp_user:
> [mta] verp_confirm_format: $address+$cookie
> [mta] verp_confirm_regexp: ^(.*<)?(?P<addr>[^+]+?)\+(?P<cookie>[^@]+)@.*$
> [mta] verp_confirmations: no
> [mta] verp_delimiter: +
> [mta] verp_delivery_interval: 0
> [mta] verp_format: ${bounces}+${local}=${domain}
> [mta] verp_personalized_deliveries: no
> [mta] verp_probe_format: $bounces+$token@$domain
> [mta] verp_probe_regexp: ^(?P<bounces>[^+]+?)\+(?P<token>[^@]+)@.*$
> [mta] verp_probes: no
> [mta] verp_regexp:
> ^(?P<bounces>[^+]+?)\+(?P<local>[^=]+)=(?P<domain>[^@]+)@.*$
> [nntp] host:
> [nntp] password:
> [nntp] port:
> [nntp] remove_headers:
> nntp-posting-host nntp-posting-date x-trace
> x-complaints-to xref date-received posted
> posting-version relay-version received
> [nntp] rewrite_duplicate_headers:
> To X-Original-To
> CC X-Original-CC
> Content-Transfer-Encoding X-Original-Content-Transfer-Encoding
> MIME-Version X-MIME-Version
> [nntp] user:
> [passwords] configuration: python:mailman.config.passlib
> [passwords] password_length: 8
> [plugin.master] class:
> [plugin.master] component_package:
> [plugin.master] configuration:
> [plugin.master] enabled: no
> [shell] banner: Welcome to the GNU Mailman shell
> [shell] history_file:
> [shell] prompt: >>>
> [shell] use_ipython: no
> [styles] default: legacy-default
> [webservice] admin_pass: ---------------------------------
> [webservice] admin_user: restadmin
> [webservice] api_version: 3.1
> [webservice] hostname: localhost
> [webservice] port: 8001
> [webservice] show_tracebacks: yes
> [webservice] use_https: no
> _______________________________________________
> Mailman-users mailing list -- mailman-users(a)mailman3.org
> To unsubscribe send an email to mailman-users-leave(a)mailman3.org
> https://lists.mailman3.org/mailman3/lists/mailman-users.mailman3.org/
> Archived at:
> https://lists.mailman3.org/archives/list/mailman-users@mailman3.org/message…
>
> This message sent to max.paragnani(a)gmail.com
>
3 years, 3 months
Re: Cannot Install Web UI
by Andreas Vetter
On Montag, 20. Oktober 2025 19:56:39 CEST Mark Sapiro wrote:
> On 10/20/25 10:32, Dennis Putnam via Mailman-users wrote:
>
> > I'm trying to install the web UI for mailman3. I am getting the
> > following failure. Can someone help? TIA.
> >
> > (venv) mailman :~$ pip install mailman-web mailman-hyperkitty
>
> ...
>
> > FileNotFoundError: [Errno 2] No such file or directory:
> >
> > '/tmp/pip-install-y364_cvm/cmarkgfm_9fcba25730114ac4a08d1e
> > 7733112a45/src/cmarkgfm/cmark.cffi.h'
> >
> > [end of output]
> >
> >
> >
> > note: This error originates from a subprocess, and is likely not a
> >
> > problem with pip.
> > error: subprocess-exited-with-error
> >
> > × Getting requirements to build wheel did not run successfully.
> > │ exit code: 1
> > ╰─> See above for output.
> >
> > note: This error originates from a subprocess, and is likely not a
> > problem with pip.
>
>
> I think I've seen a similar error, but I don't recall what I did to work
> around it. In this case cmarkgfm is a dependency of readme_renderer
> which in turn is a dependency of postorius.
> In your venv try
>
> pip install cmarkgfm
>
> first and then
>
> pip install mailman-web mailman-hyperkitty
>
> That may avoid this.
>
> --
> Mark Sapiro <mark(a)msapiro.net> The highway is for gamblers,
> San Francisco Bay Area, California better use your sense - B. Dylan
It seems to me cmarkgfm is broken today. I tried to update it in my working
environment and get the same error:
(venv) mailman@lists:~> pip install -U cmarkgfm
Requirement already satisfied: cmarkgfm in ./venv/lib64/python3.11/site-
packages (2024.11.20)
Collecting cmarkgfm
Using cached cmarkgfm-2025.10.20.tar.gz (145 kB)
Installing build dependencies ... done
Getting requirements to build wheel ... error
error: subprocess-exited-with-error
× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> [41 lines of output]
Traceback (most recent call last):
File "/opt/mailman/venv/lib64/python3.11/site-packages/pip/_vendor/
pyproject_hooks/_in_process/_in_process.py", line 389, in <module>
main()
File "/opt/mailman/venv/lib64/python3.11/site-packages/pip/_vendor/
pyproject_hooks/_in_process/_in_process.py", line 373, in main
json_out["return_val"] = hook(**hook_input["kwargs"])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/mailman/venv/lib64/python3.11/site-packages/pip/_vendor/
pyproject_hooks/_in_process/_in_process.py", line 143, in
get_requires_for_build_wheel
return hook(config_settings)
^^^^^^^^^^^^^^^^^^^^^
File "/tmp/pip-build-env-mdd_0nfr/overlay/lib/python3.11/site-
packages/setuptools/build_meta.py", line 331, in get_requires_for_build_wheel
return self._get_build_requires(config_settings, requirements=[])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/pip-build-env-mdd_0nfr/overlay/lib/python3.11/site-
packages/setuptools/build_meta.py", line 301, in _get_build_requires
self.run_setup()
File "/tmp/pip-build-env-mdd_0nfr/overlay/lib/python3.11/site-
packages/setuptools/build_meta.py", line 317, in run_setup
exec(code, locals())
File "<string>", line 5, in <module>
File "/tmp/pip-build-env-mdd_0nfr/overlay/lib/python3.11/site-
packages/setuptools/__init__.py", line 115, in setup
return distutils.core.setup(**attrs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/pip-build-env-mdd_0nfr/overlay/lib/python3.11/site-
packages/setuptools/_distutils/core.py", line 148, in setup
_setup_distribution = dist = klass(attrs)
^^^^^^^^^^^^
File "/tmp/pip-build-env-mdd_0nfr/overlay/lib/python3.11/site-
packages/setuptools/dist.py", line 321, in __init__
_Distribution.__init__(self, dist_attrs)
File "/tmp/pip-build-env-mdd_0nfr/overlay/lib/python3.11/site-
packages/setuptools/_distutils/dist.py", line 309, in __init__
self.finalize_options()
File "/tmp/pip-build-env-mdd_0nfr/overlay/lib/python3.11/site-
packages/setuptools/dist.py", line 784, in finalize_options
ep(self)
File "/tmp/pip-build-env-mdd_0nfr/overlay/lib/python3.11/site-
packages/setuptools/dist.py", line 804, in _finalize_setup_keywords
ep.load()(self, ep.name, value)
File "/tmp/pip-build-env-mdd_0nfr/overlay/lib64/python3.11/site-
packages/cffi/setuptools_ext.py", line 229, in cffi_modules
add_cffi_module(dist, cffi_module)
File "/tmp/pip-build-env-mdd_0nfr/overlay/lib64/python3.11/site-
packages/cffi/setuptools_ext.py", line 50, in add_cffi_module
execfile(build_file_name, mod_vars)
File "/tmp/pip-build-env-mdd_0nfr/overlay/lib64/python3.11/site-
packages/cffi/setuptools_ext.py", line 26, in execfile
exec(code, glob, glob)
File "src/cmarkgfm/build_cmark.py", line 21, in <module>
with open(CMARK_DEF_H_PATH, encoding='utf-8') as fh:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/pip-
install-8e12fhsc/cmarkgfm_dbeb0911a2014cbe9bb4b5b09ee7602f/src/cmarkgfm/
cmark.cffi.h'
[end of output]
note: This error originates from a subprocess, and is likely not a problem
with pip.
error: subprocess-exited-with-error
× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> See above for output.
note: This error originates from a subprocess, and is likely not a problem
with pip.
--
Mit freundlichen Gruessen,
Andreas Vetter
6 months, 1 week
Re: New releases
by Danil Smirnov
On Tue, 9 Jun 2020 at 00:05, Mark Sapiro <mark(a)msapiro.net> wrote:
> The first row of horizontal tabs is unchanged, but the `Settings` tab
> used to have a second horizontal row and now has a vertical list on the
> left.
>
Yeah Mark, thanks - now I see it :)
> After you upgraded did you run these django-admin commands?
> ```
> django-admin collectstatic --clear --noinput --verbosity 0
> django-admin compress
> django-admin compilemessages
> django-admin migrate
> ```
> These 4 commands should be run after every update to Postorius,
> HyperKitty or django_mainlman3.
>
Hm, interesting... Could you point me to some related docs please?
To upgrade, I've just bumped app versions in my Dockerfiles, built and
restarted...
Mailman-core worked right away with no issues.
Mailman-web (Hyperkitty) failed with the error:
----------
ERROR 2020-06-08 19:46:41,942 14 django.request Internal Server Error:
/hyperkitty/
Traceback (most recent call last):
File "/usr/lib/python3.6/site-packages/compressor/base.py", line 282, in
precompile
mod = import_module(mod_name)
File "/usr/lib/python3.6/importlib/__init__.py", line 126, in
import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 994, in _gcd_import
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'sassc -t compressed {infile}
{outfile}'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File
"/usr/lib/python3.6/site-packages/django/core/handlers/exception.py", line
34, in inner
response = get_response(request)
File "/usr/lib/python3.6/site-packages/django/core/handlers/base.py",
line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/usr/lib/python3.6/site-packages/django/core/handlers/base.py",
line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python3.6/site-packages/hyperkitty/views/index.py", line
118, in index
return render(request, "hyperkitty/index.html", context)
File "/usr/lib/python3.6/site-packages/django/shortcuts.py", line 36, in
render
content = loader.render_to_string(template_name, context, request,
using=using)
File "/usr/lib/python3.6/site-packages/django/template/loader.py", line
62, in render_to_string
return template.render(context, request)
File
"/usr/lib/python3.6/site-packages/django/template/backends/django.py", line
61, in render
return self.template.render(context)
File "/usr/lib/python3.6/site-packages/django/template/base.py", line
171, in render
return self._render(context)
File "/usr/lib/python3.6/site-packages/django/template/base.py", line
163, in _render
return self.nodelist.render(context)
File "/usr/lib/python3.6/site-packages/django/template/base.py", line
937, in render
bit = node.render_annotated(context)
File "/usr/lib/python3.6/site-packages/django/template/base.py", line
904, in render_annotated
return self.render(context)
File "/usr/lib/python3.6/site-packages/django/template/loader_tags.py",
line 150, in render
return compiled_parent._render(context)
File "/usr/lib/python3.6/site-packages/django/template/base.py", line
163, in _render
return self.nodelist.render(context)
File "/usr/lib/python3.6/site-packages/django/template/base.py", line
937, in render
bit = node.render_annotated(context)
File "/usr/lib/python3.6/site-packages/django/template/base.py", line
904, in render_annotated
return self.render(context)
File
"/usr/lib/python3.6/site-packages/compressor/templatetags/compress.py",
line 143, in render
return self.render_compressed(context, self.kind, self.mode,
forced=forced)
File
"/usr/lib/python3.6/site-packages/compressor/templatetags/compress.py",
line 119, in render_compressed
rendered_output = compressor.output(mode, forced=forced,
basename=file_basename)
File "/usr/lib/python3.6/site-packages/compressor/css.py", line 46, in
output
ret.append(subnode.output(*args, **kwargs))
File "/usr/lib/python3.6/site-packages/compressor/css.py", line 48, in
output
return super(CssCompressor, self).output(*args, **kwargs)
File "/usr/lib/python3.6/site-packages/compressor/base.py", line 314, in
output
output = '\n'.join(self.filter_input(forced))
File "/usr/lib/python3.6/site-packages/compressor/base.py", line 254, in
filter_input
for hunk in self.hunks(forced):
File "/usr/lib/python3.6/site-packages/compressor/base.py", line 228, in
hunks
precompiled, value = self.precompile(value, **options)
File "/usr/lib/python3.6/site-packages/compressor/base.py", line 287, in
precompile
return True, filter.input(**kwargs)
File "/usr/lib/python3.6/site-packages/compressor/filters/base.py", line
239, in input
return super(CachedCompilerFilter, self).input(**kwargs)
File "/usr/lib/python3.6/site-packages/compressor/filters/base.py", line
206, in input
raise FilterError(err)
compressor.exceptions.FilterError: Error: It's not clear which file to
import for '@import "../libs/bootstrap/stylesheets/bootstrap"'.
Candidates:
../libs/bootstrap/stylesheets/_bootstrap.scss
../libs/bootstrap/stylesheets/bootstrap.scss
Please delete or rename all but one of these files.
on line 4 of
../mailman-web-data/static/hyperkitty/sass/hyperkitty.scss
>> @import "../libs/bootstrap/stylesheets/bootstrap";
----------
I've fixed the error by removing the older file which is
/opt/mailman-web-data/static/hyperkitty/libs/bootstrap/stylesheets/_bootstrap.scss
After that everything seems to be working fine.
My best regards,
Danil Smirnov
5 years, 10 months