Odoo Error – virtual real time limit (151/120s) reached.

There are times, when you might suddenly see your Odoo is shutdown automatically, without warning. Once you enable to logging, you could see an error like the following:

virtual real time limit (151/120s) reached.

or in full details like the following

2021-04-22 06:46:44,054 32685 WARNING ? odoo.service.server: Thread <Thread(odoo.service.http.request.140015617943296, started 140015617943296)> virtual real time limit (151/120s) reached.
2021-04-22 06:46:44,054 32685 INFO ? odoo.service.server: Dumping stacktrace of limit exceeding threads before reloading
2021-04-22 06:46:44,060 32685 INFO ? odoo.tools.misc:
# Thread: <Thread(odoo.service.http.request.140015617943296, started 140015617943296)> (db:n/a) (uid:n/a) (url:n/a)
File: "/opt/rh/rh-python36/root/usr/lib64/python3.6/threading.py", line 884, in _bootstrap
  self._bootstrap_inner()
File: "/opt/rh/rh-python36/root/usr/lib64/python3.6/threading.py", line 916, in _bootstrap_inner
  self.run()
File: "/opt/rh/rh-python36/root/usr/lib64/python3.6/threading.py", line 864, in run
  self._target(*self._args, **self._kwargs)
File: "/opt/rh/rh-python36/root/usr/lib64/python3.6/socketserver.py", line 654, in process_request_thread
  self.finish_request(request, client_address)
File: "/opt/rh/rh-python36/root/usr/lib64/python3.6/socketserver.py", line 364, in finish_request
  self.RequestHandlerClass(request, client_address, self)
File: "/opt/rh/rh-python36/root/usr/lib64/python3.6/socketserver.py", line 724, in __init__
  self.handle()
File: "/opt/odoo/odoo14-venv/lib64/python3.6/site-packages/werkzeug/serving.py", line 329, in handle
  rv = BaseHTTPRequestHandler.handle(self)
File: "/opt/rh/rh-python36/root/usr/lib64/python3.6/http/server.py", line 418, in handle
  self.handle_one_request()
File: "/opt/odoo/odoo14-venv/lib64/python3.6/site-packages/werkzeug/serving.py", line 360, in handle_one_request
  self.raw_requestline = self.rfile.readline()
File: "/opt/rh/rh-python36/root/usr/lib64/python3.6/socket.py", line 586, in readinto
  return self._sock.recv_into(b)
2021-04-22 06:46:44,060 32685 INFO ? odoo.service.server: Initiating server reload

This is because Odoo is killing zombie processes and probably mistakenly crashing your Odoo completely while doing so. The parameter that is used for this purpose, can be found in Odoo documentation:

https://www.odoo.com/documentation/14.0/reference/cmdline.html

--limit-time-real <limit>
Prevents the worker from taking longer than <limit> seconds to process a request. If the limit is exceeded, the worker is killed.

Differs from --limit-time-cpu in that this is a “wall time” limit including e.g. SQL queries.

Defaults to 120.

You may start your service command with something like –limit-time-real 100000 to avoid Odoo from auto killing processes. A command could look like the following if you edit your service file located at:

/etc/systemd/system/odoo14.service

The exec would be like the following:

ExecStart=/usr/bin/scl enable rh-python36 -- /opt/odoo/odoo14-venv/bin/python3 /opt/odoo/odoo14/odoo-bin -c /etc/odoo.conf --limit-time-real=100000

Once the change is done, save the file, and reload the system daemon and restart your Odoo

systemctl daemon-reload
service odoo14 restart

How to manually install/renew Let’s Encrypt SSL in Zimbra

If you are having trouble installing Let’s Encrypt SSL with the certbot-zimbra.sh file, then probably you would need to follow this tutorial. To follow this tutorial, we first need to install certbot. certbot has a built in web server to allow you get the certificate without actually installing an extra web server or through Zimbra web server (nginx to be specific).

First, we install certbot with the following:

// install epel-release first
yum install epel-release
// install certbot from epel
yum install certbot

Once done, you may now use the following command to ensure certbot is working:

# certbot --help

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  certbot [SUBCOMMAND] [options] [-d DOMAIN] [-d DOMAIN] ...

Certbot can obtain and install HTTPS/TLS/SSL certificates.  By default,
it will attempt to use a webserver both for obtaining and installing the
certificate. The most common SUBCOMMANDS and flags are:

obtain, install, and renew certificates:
    (default) run   Obtain & install a certificate in your current webserver
    certonly        Obtain or renew a certificate, but do not install it
    renew           Renew all previously obtained certificates that are near
expiry
    enhance         Add security enhancements to your existing configuration
   -d DOMAINS       Comma-separated list of domains to obtain a certificate for

  (the certbot apache plugin is not installed)
  --standalone      Run a standalone webserver for authentication
  --nginx           Use the Nginx plugin for authentication & installation
  --webroot         Place files in a server's webroot folder for authentication
  --manual          Obtain certificates interactively, or using shell script
hooks

   -n               Run non-interactively
  --test-cert       Obtain a test certificate from a staging server
  --dry-run         Test "renew" or "certonly" without saving any certificates
to disk

manage certificates:
    certificates    Display information about certificates you have from Certbot
    revoke          Revoke a certificate (supply --cert-name or --cert-path)
    delete          Delete a certificate (supply --cert-name)

manage your account:
    register        Create an ACME account
    unregister      Deactivate an ACME account
    update_account  Update an ACME account
  --agree-tos       Agree to the ACME server's Subscriber Agreement
   -m EMAIL         Email address for important account notifications

More detailed help:

  -h, --help [TOPIC]    print this message, or detailed help on a topic;
                        the available TOPICS are:

   all, automation, commands, paths, security, testing, or any of the
   subcommands or plugins (certonly, renew, install, register, nginx,
   apache, standalone, webroot, etc.)
  -h all                print a detailed help page including all topics
  --version             print the version number
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Once you ensure certbot is installed, now you may use certbot to get the certificate, using the certbot –standalone tag. Remember to stop zimbra first, as Zimbra also runs a nginx web server, that would prevent certbot to use standalone or it’s own web server to verify certificate.

// from root, run
[root@mailapp ~]# service zimbra stop

// wait until zimbra stops, once done, use the following to get certificate for your domain/hostname in place of mail.domain.com
[root@mailapp ~]# certbot certonly --standalone -d mail.domain.com

This would get your certificate and save it in:

/etc/letsencrypt/live/mail.domain.com

Now, that folder would contain 4 files. Something like the following:

]# ls -la /etc/letsencrypt/live/mail.domain.com/
total 16
drwxr-xr-x 2 root root 4096 Apr 16 11:30 .
drwx------ 4 root root 4096 Feb 10  2020 ..
lrwxrwxrwx 1 root root   40 Apr 16 11:30 cert.pem -> ../../archive/mail.domain.com/cert8.pem
lrwxrwxrwx 1 root root   41 Apr 16 11:30 chain.pem -> ../../archive/mail.domain.com/chain8.pem
lrwxrwxrwx 1 root root   45 Apr 16 11:30 fullchain.pem -> ../../archive/mail.domain.com/fullchain8.pem
lrwxrwxrwx 1 root root   43 Apr 16 11:30 privkey.pem -> ../../archive/mail.domain.com/privkey8.pem

As you can see, these files are symbolically linked to another files, depends on how many time you are running certbot. Each time, it generates a number liker cert8.pem, the next one would be cert9.pem and so on. So the orignal files are here:

/etc/letsencrypt/archive/mail.domain.com/cert8.pem
/etc/letsencrypt/archive/mail.domain.com/chain8.pem
/etc/letsencrypt/archive/mail.domain.com/fullchain8.pem
/etc/letsencrypt/archive/mail.domain.com/privkey8.pem

Now, we have our certificates. We need to follow a couple of steps to make sure everything is set correctly.

First, zimbra SSL files are stored here

/etc/zimbra/ssl/letsencrypt

We clean all old pem files

rm -f /etc/zimbra/ssl/letsencrypt/*

Now, copy the pem files we got to this folder with the following:

cp /etc/letsencrypt/archive/mail.domain.com/cert8.pem /opt/zimbra/ssl/letsencrypt/cert.pem
cp /etc/letsencrypt/archive/mail.domain.com/chain8.pem /opt/zimbra/ssl/letsencrypt/chain.pem
cp /etc/letsencrypt/archive/mail.domain.com/fullchain8.pem /opt/zimbra/ssl/letsencrypt/fullchain.pem
cp /etc/letsencrypt/archive/mail.domain.com/privkey8.pem /opt/zimbra/ssl/letsencrypt/privkey.pem

Check, how we are renaming all the files with number to file name without number, like cert8.pem is moved as cert.pem here.

Now, change the ownership of these files to zimbra with the following:

chown -Rf zimbra:zimbra /opt/zimbra/ssl/letsencrypt/*

Now, we are done from root, change your ownership to zimbra

su - zimbra

First job, is to change your directory to the ‘/opt/zimbra/ssl/letsencrypt/’

cd /opt/zimbra/ssl/letsencrypt/

Let’s Encrypt files are very much ready to use, only with one problem. Let’s Encrypt do not add it’s root CA certificate with it’s chain.pem file. We need to do this. First open the certificate with nano editor as following:

nano chain.pem

Now, at the end of the file, add the following section:

-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----

After adding the above, your chain.pem file should look like the following

-----BEGIN CERTIFICATE-----
your chain pem encrypted certificate here
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----

Now, save the file (CTRL + o) and exit (CTRL + x)

We need to do one more thing before we are ready to verify and deploy the certificate. We need to set the letencrypt private key that we used to generate the certificate as commercial.key of zimbra. You may do this with the following two commands:

rm -f /opt/zimbra/ssl/zimbra/commercial/commercial.key
cp /opt/zimbra/ssl/letsencrypt/privkey.pem /opt/zimbra/ssl/zimbra/commercial/commercial.key

Now, you are ready to complete the job. First verify if everything is alright with the following:

[zimbra@mailapp letsencrypt]$ /opt/zimbra/bin/zmcertmgr verifycrt comm privkey.pem cert.pem chain.pem
** Verifying 'cert.pem' against 'privkey.pem'
Certificate 'cert.pem' and private key 'privkey.pem' match.
** Verifying 'cert.pem' against 'chain.pem'
Valid certificate chain: cert.pem: OK

If everything is ok, you may now deploy certificate with the following command:

/opt/zimbra/bin/zmcertmgr deploycrt comm cert.pem chain.pem

Once the certificate is deployed successfully, get out from the zimbra user to root user with the following command

exit

Now, you may start/restart zimbra with the following command:

service zimbra restart

If everything went right, you should now be able to go to your zimbra domain, and under the lock sign on the left of the domain shown in browser, you may click on it to see the extended date of ssl expiry. Sweet!

How to Fix – Rongta 80mm Thermal Printer – Firefox – ‘an unknown error occurred while printing’

Rongta 80mm Thermal printer is the most popular POS receipt printer in the world. It can run on a regular 80mm printer driver for windows. It is possible to print receipts from a web browser like firefox or chrome to Rongta printers. Although there are times, it might become hectic with different printing issues to send the printing data to the printer from the browser.

If you are trying to print your POS receipt from Firefox for a Rongta printer, a common problem, that appears time to time, is the following:

An unknown error occurred while printing

You probably failed to resolve the issue, even after uninstalling the Firefox or by Refreshing Firefox settings, or by clearing the printer saved settings on your browser. The issue is very weird. For some reason, Javascript’s window print fails to send the data to Printer through firefox, even though it thinks it did. I tried digging several things, but nothing worked until I found a way to actually make firefox think, it’s a new printer. Here are the steps you may following.

  1. Close the firefox, and make your Rongta 80mm printer the default printer of your system.
  2. Now open firefox, and type ‘about:support’ & enter.
  3. It will open a page. Scroll down to the printing section where it says Troubleshooting with ‘Clear saved print settings’. Click on the button to clear the settings.
  4. From the top press ‘Refresh Firefox’ button.
  5. Now restart your firefox, and type ‘about:config’. These is the firefox configurable environmental variables, that we wish to change some.
  6. Before we do, we first need to make firefox save, Rongta settings. One quick way of doing this is to open a new tab, browse google.com, now go to Print from the File tab, it will show you ‘Advanced Preference’, now from the Print button at the top, make sure Rongta 80mm printer is selected and press Print. It will probably not print anything, but what it will help to do, is creating our printer settings in firefox.
  7. Now go back to the tab with ‘about:config’, at the top, type ‘print’ without quotes in the box that says ‘Search for preference’
  8. A lot of settings should appear, a couple of things you need to change.
  9. Delete print_printer or print.print_printer row.
  10. Set print.print_via_parent boolean value to ‘true’.
  11. Set print.tab_modal.enabled to ‘false’
  12. Make sure dom.enable_window_print this is set to ‘true’
  13. Make sure print.show_print_progress is set to ‘true’
  14. Now, close the window, and restart your firefox again.

You should now be able to print your POS receipt using Rongta 80mm printer using Firefox.

How to Setup Odoo 14 in CentOS 7

Odoo is currently one of the most popular tool for business purposes. It has a community edition, that allows managing ERP at very low cost. Odoo was previously known as OpenERP. Odoo requires to be installed on a dedicated server or VPS. Odoo 14 had come out already. I will have a straight forward how to on installing the latest Odoo 14 in CentOS 7.

Log in to your system and update

First step would be to login to your system and then update the system using yum.

ssh root@server_ip

You may check the CentOS version from the redhat release file using the following:

cat /etc/redhat-release

It should show you something like the following if you

CentOS Linux release 7.8.2003 (Core)

Now, you may try updating the system with yum

yum update -y

Once done, now install the EPEL repository as we need it to satisfy a couple of dependecies:

yum install epel-release

Install Python 3.6 packages and Odoo dependencies

We need Python 3.6 at least to run Odoo 14. Odoo 13 also ran on Python 3.6. We will use ‘Software Collection (scl)’ repository to install and use Python 3.6. To find the available Python versions in SCL, you may check the following:

SCL Repository for Python

Now, to install Python 3.6 using SCL, we first need to install the SCL repository for Centos:

yum install centos-release-scl

Once the SCL is loaded, now, you may install the python 3.6 using the following command:

yum install rh-python36

Once the Python is installed, now we will install several tools and packages for Odoo dependencies with the following command:

yum install git gcc nano wget nodejs-less libxslt-devel bzip2-devel openldap-devel libjpeg-devel freetype-devel

Create Odoo User

We now need to create a system user and group for Odoo and define a home directory to /opt/odoo

useradd -m -U -r -d  /opt/odoo -s /bin/bash odoo

You may use any username here, but remember to create the same username for the PostgreSQL as well.

Install PostgreSQL

CentOS base repository unfortunately, comes with Postgresql 9.2. But we want to use PostgreSQL 10 for our Odoo installation. You may check the available PostgreSQL for CentOS 7 using the following command:

yum list postgresql*

As by default CentOS 7 does not provide the PostgreSQL 10, we would use PostgreSQL official repository to download and install the 10 version.

First, we install the Postgres Yum Repository using the following command:

yum install https://download.postgresql.org/pub/repos/yum/10/redhat/rhel-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

Now, you may install PostgreSQL 10 and related required packages using the following command:

yum install postgresql10 postgresql10-server postgresql10-contrib postgresql10-libs -y

Now, we need to initialize the postgres database and start it. You may do that using the following:

# Initialize the DB
/usr/pgsql-10/bin/postgresql-10-setup initdb

# Start the database
systemctl start postgresql-10.service

If everything goes alright, now you may check the postgresql 10 status:

[root@docker bin]# systemctl status postgresql-10.service
● postgresql-10.service - PostgreSQL 10 database server
   Loaded: loaded (/usr/lib/systemd/system/postgresql-10.service; disabled; vendor preset: disabled)
   Active: active (running) since Mon 2021-04-05 16:42:15 EDT; 5s ago
     Docs: https://www.postgresql.org/docs/10/static/
  Process: 6380 ExecStartPre=/usr/pgsql-10/bin/postgresql-10-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
 Main PID: 6386 (postmaster)
    Tasks: 8
   Memory: 13.5M
   CGroup: /system.slice/postgresql-10.service
           ├─6386 /usr/pgsql-10/bin/postmaster -D /var/lib/pgsql/10/data/
           ├─6388 postgres: logger process
           ├─6390 postgres: checkpointer process
           ├─6391 postgres: writer process
           ├─6392 postgres: wal writer process
           ├─6393 postgres: autovacuum launcher process
           ├─6394 postgres: stats collector process
           └─6395 postgres: bgworker: logical replication launcher

Now you may enable Postgres to start when booting up using the systemctl enable command:

systemctl enable postgresql-10.service

Now, we need to create a database user for our Odoo installation. You may do that using the following:

su - postgres -c "createuser -s odoo"

Note: If you have created a different user for Odoo installation other than ‘odoo’ than you should change the username here as well.

Install Wkhtmltopdf

Wkhtmltopdf is a open source tool to make html in pdf format so that you may print pdf reports. This tool is used by Odoo and requires to be installed as dependency. CentOS 7 repository does not provide the latest version of this tool, and Odoo requires you to use the latest version. Hence, we require to download the latest version from the Wkhtmltopdf website and install it. To do that, you may first visit the page:

https://wkhtmltopdf.org/downloads.html

The page gives you the direct rpm download link for each version of CentOS/Ubuntu/Mac etc. Download the stable version for CentOS 7. At the time of writing, the URL for CentOS 7 x86_64 bit is the following:

https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox-0.12.6-1.centos7.x86_64.rpm

You may install this using the following:

cd /opt/
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox-0.12.6-1.centos7.x86_64.rpm
yum localinstall wkhtmltox-0.12.6-1.centos7.x86_64.rpm

Install and Configure Odoo 14

If you have come all through here, that means you are done with the all dependency installations before starting to download Odoo 14 source code. We will download Odoo 14 from it’s Github repo and use virtualenv to create an isolated python environment to install this python software.

First, login as odoo from root:

su - odoo

Clone the Odoo source code from Github repository:

git clone https://www.github.com/odoo/odoo --depth 1 --branch 14.0 /opt/odoo/odoo14

This will bring the Odoo 14 branch from the Odoo repository and put it inside the folder /opt/odoo/odoo14

Now, we need to enable software collections in order to access python binaries:

scl enable rh-python36 bash

Then we need to create a virtual environment to complete the installation:

cd /opt/odoo
python3 -m venv odoo14-venv

Now, you may activate the virtual environment you have just created:

source odoo14-venv/bin/activate

Now, we upgrade the pip and install the wheel library:

pip install --upgrade pip
pip3 install wheel

Once done, now we can using pip3 to install all the required Python modules from the requirements.txt file:

pip3 install -r odoo14/requirements.txt

Once the installation is complete, now we can deactivate the virtual environment and get back to the root user

deactivate && exit ; exit

If you think, you will create custom modules, you may now create it and give odoo the permission accordingly:

mkdir /opt/odoo/odoo14-custom-addons
chown odoo: /opt/odoo/odoo14-custom-addons

Now, we can fill up the odoo configuration file. First open the odoo.conf file:

nano /etc/odoo.conf

You may paste the following inside:

[options]
; This is the password that allows database operations:
admin_passwd = set_the_password_to_create_odoo_database
db_host = False
db_port = False
db_user = odoo
db_password = False
addons_path = /opt/odoo/odoo14/addons,/opt/odoo/odoo14-custom-addons
; You can enable log file with uncommenting the next line
; logfile = /var/log/odoo14/odoo.log

Please do not forget to change the password ‘set_the_password_to_create_odoo_database’ with a new strong password. This would be used to create Odoo databases from the login screen.

Create the systemd service file and start Odoo 14

Now, we will create a service file, to be able to start, stop and restart Odoo daemon. To do that, first create a service file using the following:

nano /etc/systemd/system/odoo14.service
[Unit]
Description=Odoo14
Requires=postgresql-10.service
After=network.target postgresql-10.service
[Service]
Type=simple
SyslogIdentifier=odoo14
PermissionsStartOnly=true
User=odoo
Group=odoo
ExecStart=/usr/bin/scl enable rh-python36 -- /opt/odoo/odoo14-venv/bin/python3 /opt/odoo/odoo14/odoo-bin -c /etc/odoo.conf
StandardOutput=journal+console
[Install]
WantedBy=multi-user.target

Now, save the file and exit.

Now, you need to reload the systemd daemon to be able to read the latest changes you have made to services. To do that, run:

systemctl daemon-reload

Finally, now we can start Odoo 14 instance using the following command:

systemctl start odoo14

If you are interested to check the status of the instance, you may do this:

systemctl status odoo14

It show green active running, if everything worked out. If you see no error, you may now enable Odoo to start during the boot:

systemctl enable odoo14

If you would like to see the logs, you may either use the journal tools like the following:

journalctl -u odoo14

or uncomment the following line to log the debugs in /etc/odoo.conf

logfile = /var/log/odoo14/odoo.log

After making any change to /etc/odoo.conf, do not forget the restart the Odoo14 instance using systemctl.

Test the Installation


Odoo is currently one of the most popular tool for business purposes. It has a community edition, that allows managing ERP at very low cost. Odoo was previously known as OpenERP. Odoo requires to be installed on a dedicated server or VPS. Odoo 13 had come out on October, 2019. Odoo 14 hasn’t been released yet for production. I will have a straight forward how to on installing the latest Odoo 13 in CentOS 7.

Log in to your system and update

First step would be to login to your system and then update the system using yum.ssh root@server_ip

You may check the CentOS version from the redhat release file using the following:cat /etc/redhat-release

It should show you something like the following if youCentOS Linux release 7.8.2003 (Core)

Now, you may try updating the system with yumyum update -y

Once done, now install the EPEL repository as we need it to satisfy a couple of dependecies:yum install epel-release

Install Python 3.6 packages and Odoo dependencies

We need Python 3.6 at least to run Odoo 13. Odoo 12 had support for Python 3.5, unfortunately, Odoo 13 doesn’t. We will use ‘Software Collection (scl)’ repository to install and use Python 3.6. To find the available Python versions in SCL, you may check the following:

SCL Repository for Python

Now, to install Python 3.6 using SCL, we first need to install the SCL repository for Centos:yum install centos-release-scl

Once the SCL is loaded, now, you may install the python 3.6 using the following command:yum install rh-python36

Once the Python is installed, now we will install several tools and packages for Odoo dependencies with the following command:yum install git gcc nano wget nodejs-less libxslt-devel bzip2-devel openldap-devel libjpeg-devel freetype-devel

Create Odoo User

We now need to create a system user and group for Odoo and define a home directory to /opt/odoouseradd -m -U -r -d /opt/odoo -s /bin/bash odoo

You may use any username here, but remember to create the same username for the PostgreSQL as well.

Install PostgreSQL

CentOS base repository unfortunately, comes with Postgresql 9.2. But we want to use PostgreSQL 9.6 for our Odoo installation. You may check the available PostgreSQL for CentOS 7 using the following command:yum list postgresql*

As by default CentOS 7 does not provide the PostgreSQL 9.6, we would use PostgreSQL official repository to download and install the 9.6 version.

First, we install the Postgres Yum Repository using the following command:yum install https://download.postgresql.org/pub/repos/yum/9.6/redhat/rhel-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

Now, you may install PostgreSQL 9.6 and related required packages using the following command:yum install postgresql96 postgresql96-server postgresql96-contrib postgresql96-libs

Now, we need to initialize the postgres database and start it. You may do that using the following:# Initialize the DB/usr/pgsql-9.6/bin/postgresql96-setup initdb# Start the databasesystemctl start postgresql-9.6.service

Now you may enable Postgres to start when booting up using the systemctl enable command:systemctl enable postgresql-9.6.service

Now, we need to create a database user for our Odoo installation. You may do that using the following:su – postgres -c “createuser -s odoo”

Note: If you have created a different user for Odoo installation other than ‘odoo’ than you should change the username here as well.

Install Wkhtmltopdf

Wkhtmltopdf is a open source tool to make html in pdf format so that you may print pdf reports. This tool is used by Odoo and requires to be installed as dependency. CentOS 7 repository does not provide the latest version of this tool, and Odoo requires you to use the latest version. Hence, we require to download the latest version from the Wkhtmltopdf website and install it. To do that, you may first visit the page:https://wkhtmltopdf.org/downloads.html

The page gives you the direct rpm download link for each version of CentOS/Ubuntu/Mac etc. Download the stable version for CentOS 7. At the time of writing, the URL for CentOS 7 x86_64 bit is the following:https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox-0.12.6-1.centos7.x86_64.rpm

You may install this using the following:cd /opt/wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox-0.12.6-1.centos7.x86_64.rpmyum localinstall wkhtmltox-0.12.6-1.centos7.x86_64.rpm

Install and Configure Odoo 13

If you have come all through here, that means you are done with the all dependency installations before starting to download Odoo 13 source code. We will download Odoo 13 from it’s Github repo and use virtualenv to create an isolated python environment to install this python software.

First, login as odoo from root:su – odoo

Clone the Odoo source code from Github repository:git clone https://www.github.com/odoo/odoo –depth 1 –branch 13.0 /opt/odoo/odoo13

This will bring the Odoo 13 branch from the Odoo repository and put it inside the folder /opt/odoo/odoo13

Now, we need to enable software collections in order to access python binaries:scl enable rh-python36 bash

Then we need to create a virtual environment to complete the installation:cd /opt/odoopython3 -m venv odoo13-venv

Now, you may activate the virtual environment you have just created:source odoo13-venv/bin/activate

Now, we upgrade the pip and install the wheel library:pip install –upgrade pippip3 install wheel

Once done, now we can using pip3 to install all the required Python modules from the requirements.txt file:pip3 install -r odoo13/requirements.txt

Once the installation is complete, now we can deactivate the virtual environment and get back to the root userdeactivate && exit ; exit

If you think, you will create custom modules, you may now create it and give odoo the permission accordingly:mkdir /opt/odoo/odoo13-custom-addonschown odoo: /opt/odoo/odoo13-custom-addons

Now, we can fill up the odoo configuration file. First open the odoo.conf file:nano /etc/odoo.conf

You may paste the following inside:[options]; This is the password that allows database operations:admin_passwd = set_the_password_to_create_odoo_databasedb_host = Falsedb_port = Falsedb_user = odoodb_password = Falseaddons_path = /opt/odoo/odoo13/addons,/opt/odoo/odoo13-custom-addons; You can enable log file with uncommenting the next line; logfile = /var/log/odoo13/odoo.log

Please do not forget to change the password ‘set_the_password_to_create_odoo_database’ with a new strong password. This would be used to create Odoo databases from the login screen.

Create the systemd service file and start Odoo 13

Now, we will create a service file, to be able to start, stop and restart Odoo daemon. To do that, first create a service file using the following:nano /etc/systemd/system/odoo13.service

and paste the following:[Unit]Description=Odoo13Requires=postgresql-9.6.serviceAfter=network.target postgresql-9.6.service[Service]Type=simpleSyslogIdentifier=odoo13PermissionsStartOnly=trueUser=odooGroup=odooExecStart=/usr/bin/scl enable rh-python35 — /opt/odoo/odoo13-venv/bin/python3 /opt/odoo/odoo13/odoo-bin -c /etc/odoo.confStandardOutput=journal+console[Install]WantedBy=multi-user.target

Now, save the file and exit.

Now, you need to reload the systemd daemon to be able to read the latest changes you have made to services. To do that, run:systemctl daemon-reload

Finally, now we can start Odoo 13 instance using the following command:systemctl start odoo13

If you are interested to check the status of the instance, you may do this:systemctl status odoo13[root@hr ~]# systemctl status odoo13● odoo13.service – Odoo13 Loaded: loaded (/etc/systemd/system/odoo13.service; enabled; vendor preset: disabled) Active: active (running) since Sun 2020-09-13 08:26:46 EDT; 23h ago Main PID: 24502 (scl) CGroup: /system.slice/odoo13.service ├─24502 /usr/bin/scl enable rh-python36 — /opt/odoo/odoo13-venv/bin/python3 /opt/odoo/odoo13/odoo-bin -c /etc/odoo.conf ├─24503 /bin/bash /var/tmp/sclSWH04z └─24507 /opt/odoo/odoo13-venv/bin/python3 /opt/odoo/odoo13/odoo-bin -c /etc/odoo.conf

It show green active running, if everything worked out. If you see no error, you may now enable Odoo to start during the boot:systemctl enable odoo13

If you would like to see the logs, you may either use the journal tools like the following:journalctl -u odoo13

or uncomment the following line to log the debugs in /etc/odoo.conflogfile = /var/log/odoo13/odoo.log

After making any change to /etc/odoo.conf, do not forget the restart the Odoo13 instance using systemctl.

Test the Installation

You may now test the installation using http://your_server_ip:8069. If everything worked, it should come up. If it doesn’t, you may try stopping your ‘firewalld’ to see if firewall is blocking the port or not:

systemctl stop firewalld

At Mellowhost, we provide Odoo installation and configuration assistance for absolute free of charge. If you are willing to try out any of our VPS for Odoo, you may do so and talk with us through the Live chat or the ticket for Odoo assistance.

Furthermore, Good luck.

How to Speed Up Software RAID (mdadm) Resync Speed

mdadm is the software raid tools used in Linux system. One key problem with the software raid, is that it resync is utterly slow comparing with the existing drive speed (SSD or NVMe). The resync speed set by mdadm is default for regardless of whatever the drive type you have. To view the default values, you may run the following:

[root@172 ~]# sysctl dev.raid.speed_limit_min
dev.raid.speed_limit_min = 1000
[root@172 ~]# sysctl dev.raid.speed_limit_max
dev.raid.speed_limit_max = 200000

As you see, the minimum value starts from 1000 and can max upto 200K. Although, it can max upto 200K, but as min value is too low, mdadm always tries to keep the value below average to your speed available. To speed up, we would like to maximize these numbers. To change the numbers, you may run something like the following:

sysctl -w dev.raid.speed_limit_min=500000
sysctl -w dev.raid.speed_limit_max=5000000

Once done, you may now check the speed is going up immediately:

[root@172 ~]# cat /proc/mdstat
Personalities : [raid1]
md3 : active raid1 sdb5[1] sda5[0]
      1916378112 blocks super 1.2 [2/2] [UU]
      [===============>.....]  resync = 76.2% (1461787904/1916378112) finish=27.4min speed=276182K/sec
      bitmap: 5/15 pages [20KB], 65536KB chunk

md0 : active raid1 sdb1[1] sda1[0]
      1046528 blocks super 1.2 [2/2] [UU]
      bitmap: 0/1 pages [0KB], 65536KB chunk

md2 : active raid1 sda2[0] sdb2[1]
      78576640 blocks super 1.2 [2/2] [UU]
      bitmap: 1/1 pages [4KB], 65536KB chunk

md1 : active raid1 sdb3[1] sda3[0]
      4189184 blocks super 1.2 [2/2] [UU]

unused devices: <none>

One thing to keep in mind is that, if you try to set the value too high, like we did, this might cause some handsome load on your system. If you see the load is unmanageable, you should focus on decreasing the number to something like 50k-100k for the min value.

Making The Sysctl Value Permanent

As we have established the kernel variable values on runtime, this would go back to default once we restart/reboot the server. If you want to persist the values, you need to put these values to /etc/sysctl.conf file. To make them persist, open the sysctl.conf file:

nano /etc/sysctl.conf

Add the following lines at the end of the file:

dev.raid.speed_limit_min = 500000
dev.raid.speed_limit_max = 5000000

Save the file, and run the following command:

sysctl -p

This should persist your values for those variables after the reboot as well as runtime.

-bash: smartctl: command not found

Error Details

When I try to check the S.M.A.R.T details of my drive, using the following command:

smartctl -a /dev/sda

I get an error:

-bash: smartctl: command not found

What can I do?

Solution

This error is appearing because you do not have the S.M.A.R.T tools installed on your system.

How to Install Smart tools on CentOS 7?

To install smart tools, you can run the following:

yum install smartmontools -y

Once done, you may run the smartctl command again, and it shall work:

[root@172 ~]# smartctl -a /dev/sda
smartctl 7.0 2018-12-30 r4883 [x86_64-linux-3.10.0-1127.el7.x86_64] (local build)
Copyright (C) 2002-18, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Family:     Crucial/Micron BX/MX1/2/3/500, M5/600, 1100 SSDs
Device Model:     Micron_1100_MTFDDAK2T0TBN

How to Disable Clamd & Spamassasign in Virtualmin

Question

My clamscan is taking a lot of CPU & memory of my vps. I use Virtualmin as the control panel. How can I disable Clamscan and Spamassign from taking excessive cpu and memory?

Solution

If you are receiving an inbound spam attack or an email bounce attack on your VPS, and you use Clamscan and Spamassasign for your incoming mail filtering, it is highly possible that, you will run out of RAM and CPU. To solve the problem, you need to disable Clamscan and Spamassign for at least the time you are dealing with the attack or have developed a way to deal the attack. To disable Clamd and Spamassasign, you may follow the following steps

How to Disable Clamd and Spamassasign

First login to your virtualmin 10000 port, and go to System Settings >> Features and Plugins

Now uncheck the options ‘Spam filtering’ and ‘Virus filtering’ option and save it

Now go to your Webmin tab >> Under the System >> Bootup and Shutdown

Now select the services with the name ‘clam’ and ‘spamassassin.service’, then click on ‘Disable now and on boot’ option. Once saved, also make sure they are saying ‘No’ in running. If not, select them again and go to the bottom of the page, and press ‘Stop’ to shut them down immediately.

How to Restart Virtualmin / Webmin

Question

How to restart Virtualmin control panel?

Solution

If you are using virtualmin as a control panel, you use 10000 port to login to your control panel. It shall look like the following:

https://your.hostname.com:10000

Now, if your browser says something like the following:

It means your webmin is either down or crashed.

Restart Virtualmin or Restart Webmin

To solve this, you may start the webmin by logging to your SSH and running the following command:

service webmin start
or
/etc/init.d/webmin start

In case, you need to double sure to stop the service, you may do the following:

service webmin stop
or
/etc/init.d/webmin stop

Once you done, stopping, make sure to start it with the following:

service webmin start
or
/etc/init.d/webmin start

Once the webmin starts successfully, you may access your virtulmin control panel on port 10000, either with your hostname or the IP, like the following:

https://your.hostname.com:10000
or
https://11.11.11.11:10000
(replace 11.11.11.11 with your server IP)

How to Change memory_limit in Virtualmin

Question

I want to change the memory_limit of a virtual host in virtualmin. How can I do that?

Solution

First, login to Virtualmin on port 10000, now, select the virtual host from the dropdown under Virtualmin tab. Now under the services, there are PHP 5 Configuration and PHP 7 Configuration

Click on the version you want to change configuration for. It will show you a list of options to change php variables.

Now there is ‘Resource Limit’, that contains the options like maximum execution time, or memory limit for PHP.

Now, change the ‘Maximum Memory Allocation’ option to something that you want to change memory_limit of php in virtualmin

Server Boots to Grub – OVH Servers – How to Fix

Error Details

After you have completed updating your yum, you saw the kernel got updated, and hence restarted the server to take the new kernel. But you find out that the server has never come online. Once you visit the KVM or Serial Console (SOL) of the system, you could see, your system is booted to ‘grub>’ console instead of booting from disk. How can you fix the system now?

Solution Intro

This specific issue can appear for any linux server, along with many reasons. Although, if you are running an server from OVH and had faced a similar issue, the boat I am going to show you can navigate to destination. Please note, in many other case of similar situation, you might end up fixing the grub with the same solution.

What and How the Problem Happened

OVH has an interesting strategy of booting. They follow everything through network PXE, even if it is not ‘netboot’, but just the local drives. For this to work out, you need PXE to take the latest grub details pushed once a kernel is updated. This is one reason why, OVH also supplies a custom kernel from a cusstom repo. Although, if you are using the stock kernel, you might come up with a situation, where the latest grub hasn’t been pushed to PXE and your system fails to boot from drives. It then puts you in the ‘grub’ of network.

How to Fix the Problem

Now, one thing is clear, after you completed a kernel update, your grub is broken due to the latest machine code is not available to the booting system. You can go and follow a regular grub repair method for Grub 2, to fix the situation. A couple of things to remember, as your system’s grub is failing to load, you have to use an independent rescue kernel to fix this, this could either be from a personal network repository or a rescue disk available from your datacenter’s location, like ovh has one. Another thing to remember, is that, if you are using CentOS 7 or Ubuntu with UEFI system, using mdadm or linux software raid, it is highly likely, your boot efi is placed in a non raid partition. Preferably in the first drive’s first partition. You can always verify this from your fstab file.

So the first job, is to boot your system into the rescue disk/cd/kernel. I assume you have done that with no difficulty. Once done, first mount your partitions. In OVH cases, it loads the mdadm automatically. In my case, it was /dev/md2.

mount /dev/md2 /mnt
# check what partition is used for /boot/efi
nano /mnt/etc/fstab
# in my case, it is /dev/nvme0n1p1 (It is a NVMe SSD, and the first partion is used for efi storage
mount /dev/nvme0n1p1 /mnt/boot/efi

Once we have mounted the partitions successfully, you may now chroot the system. Before chrooting, you want the dev, proc and sys to use the /mnt partitions respectively:

mount --bind /dev /mnt/dev
mount --bind /proc /mnt/proc
mount --bind /sys /mnt/sys

If these all goes well, now we can chroot the system:

chroot /mnt

Now you have successfully changed the root directory of the rescue kernel to the original drive’s root. All you need to do, is to remake the grub config, that will immediately generate the grub.cfg file and sync the machine code:

# we know grub.cfg is available in /boot/grub2/grub.cfg
grub2-mkconfig -o  /boot/grub2/grub.cfg
# once this is finished, we have to make sure, grub is also installed for both disks, for my case, these are /dev/nvme0n1 and /dev/nvme1n1
grub2-install /dev/nvme0n1
grub2-install /dev/nvme1n1

If you see the response is ‘No Error Reported’, then you are good go. You may now reboot your system back to hard disk, and can see your grub is able to load the latest kernel you installed from the original hard disk. Remember, for safety, you should umount all the partition, to avoid any data loss due to OS page cache:

# exit from chroot
exit
# unmount dev, proc, sys, /mnt/boot/efi, /mnt
umount /dev
umount /proc
umount /sys
umount /mnt/boot/efi
umount /mnt

Happy troubleshooting!