:code-column: .. _reference/upgrade-api: ================ Database Upgrade ================ Introduction ~~~~~~~~~~~~ This document describes the API used to upgrade an Odoo database to a higher version. It allows a database to be upgraded without ressorting to the html form at https://upgrade.odoo.com Although the database will follow the same process described on that form. The required steps are: * :ref:`creating a request ` * :ref:`uploading a database dump ` * :ref:`running the upgrade process ` * :ref:`obtaining the status of the database request ` * :ref:`downloading the upgraded database dump ` The methods ~~~~~~~~~~~ .. _upgrade-api-create-method: Creating a database upgrade request =================================== This action creates a database request with the following information: * your contract reference * your email address * the target version (the Odoo version you want to upgrade to) * the purpose of your request (test or production) * the database dump name (required but purely informative) * optionally the server timezone (for Odoo source version < 6.1) The ``create`` method --------------------- .. py:function:: https://upgrade.odoo.com/database/v1/create Creates a database upgrade request :param str contract: (required) your enterprise contract reference :param str email: (required) your email address :param str target: (required) the Odoo version you want to upgrade to. Valid choices: 11.0, 12.0, 13.0 :param str aim: (required) the purpose of your upgrade database request. Valid choices: test, production. :param str filename: (required) a purely informative name for you database dump file :param str timezone: (optional) the timezone used by your server. Only for Odoo source version < 6.1 :return: request result :rtype: JSON dictionary The *create* method returns a JSON dictionary containing the following keys: .. _upgrade-api-json-failure: ``failures`` '''''''''''' The list of errors. A list of dictionaries, each dictionary giving information about one particular error. Each dictionary can contain various keys depending of the type of error but you will always get the ``reason`` and the ``message`` keys: * ``reason``: the error type * ``message``: a human friendly message Some possible keys: * ``code``: a faulty value * ``value``: a faulty value * ``expected``: a list of valid values See a sample output aside. .. rst-class:: setup doc-aside .. switcher:: .. code-block:: json { "failures": [ { "expected": [ "11.0", "12.0", "13.0", ], "message": "Invalid value \"5.0\"", "reason": "TARGET:INVALID", "value": "5.0" }, { "code": "M123456-abcxyz", "message": "Can not find contract M123456-abcxyz", "reason": "CONTRACT:NOT_FOUND" } ] } ``request`` ''''''''''' If the *create* method is successful, the value associated to the *request* key will be a dictionary containing various information about the created request: The most important keys are: * ``id``: the request id * ``key``: your private key for this request These 2 values will be requested by the other methods (upload, process and status) The other keys will be explained in the section describing the :ref:`status method `. Sample script ''''''''''''' Here are 2 examples of database upgrade request creation using: * one in the python programming language using the requests library * one in the bash programming language using `curl `_ (tool for transfering data using http) and `jq `_ (JSON processor): .. rst-class:: setup doc-aside .. switcher:: .. code-block:: python import requests CREATE_URL = "https://upgrade.odoo.com/database/v1/create" CONTRACT = "M123456-abcdef" AIM = "test" TARGET = "12.0" EMAIL = "john.doe@example.com" FILENAME = "db_name.dump" fields = dict([ ('aim', AIM), ('email', EMAIL), ('filename', DB_SOURCE), ('contract', CONTRACT), ('target', TARGET), ]) r = requests.get(CREATE_URL, data=fields) print(r.text) .. code-block:: bash CONTRACT=M123456-abcdef AIM=test TARGET=12.0 EMAIL=john.doe@example.com FILENAME=db_name.dump CREATE_URL="https://upgrade.odoo.com/database/v1/create" URL_PARAMS="contract=${CONTRACT}&aim=${AIM}&target=${TARGET}&email=${EMAIL}&filename=${FILENAME}" curl -sS "${CREATE_URL}?${URL_PARAMS}" > create_result.json # check for failures failures=$(cat create_result.json | jq -r '.failures[]') if [ "$failures" != "" ]; then echo $failures | jq -r '.' exit 1 fi .. _upgrade-api-upload-method: Uploading your database dump ============================ There are 2 methods to upload your database dump: * the ``upload`` method using the HTTPS protocol * the ``request_sftp_access`` method using the SFTP protocol The ``upload`` method --------------------- It's the most simple and most straightforward way of uploading your database dump. It uses the HTTPS protocol. .. py:function:: https://upgrade.odoo.com/database/v1/upload Uploads a database dump :param str key: (required) your private key :param str request: (required) your request id :return: request result :rtype: JSON dictionary The request id and the private key are obtained using the :ref:`create method ` The result is a JSON dictionary containing the list of ``failures``, which should be empty if everything went fine. .. rst-class:: setup doc-aside .. switcher:: .. code-block:: python import requests UPLOAD_URL = "https://upgrade.odoo.com/database/v1/upload" DUMPFILE = "/tmp/dump.sql" fields = dict([ ('request', '10534'), ('key', 'Aw7pItGVKFuZ_FOR3U8VFQ=='), ]) headers = {"Content-Type": "application/octet-stream"} with open(DUMPFILE, 'rb') as f: requests.post(UPLOAD_URL, data=f, params=fields, headers=headers) .. code-block:: bash UPLOAD_URL="https://upgrade.odoo.com/database/v1/upload" DUMPFILE="openchs.70.cdump" KEY="Aw7pItGVKFuZ_FOR3U8VFQ==" REQUEST_ID="10534" URL_PARAMS="key=${KEY}&request=${REQUEST_ID}" HEADER="Content-Type: application/octet-stream" curl -H $HEADER --data-binary "@${DUMPFILE}" "${UPLOAD_URL}?${URL_PARAMS}" .. _upgrade-api-request-sftp-access-method: The ``request_sftp_access`` method ---------------------------------- This method is recommanded for big database dumps. It uses the SFTP protocol and supports resuming. It will create a temporary SFTP server where you can connect to and allow you to upload your database dump using an SFTP client. .. py:function:: https://upgrade.odoo.com/database/v1/request_sftp_access Creates an SFTP server :param str key: (required) your private key :param str request: (required) your request id :param str ssh_keys: (required) the path to a file listing the ssh public keys you'd like to use :return: request result :rtype: JSON dictionary The request id and the private key are obtained using the :ref:`create method ` The file listing your ssh public keys should be roughly similar to a standard ``authorized_keys`` file. This file should only contains public keys, blank lines or comments (lines starting with the ``#`` character) Your database upgrade request should be in the ``draft`` state. The ``request_sftp_access`` method returns a JSON dictionary containing the following keys: .. rst-class:: setup doc-aside .. switcher:: .. code-block:: python import requests UPLOAD_URL = "https://upgrade.odoo.com/database/v1/request_sftp_access" SSH_KEY = "$HOME/.ssh/id_rsa.pub" SSH_KEY_CONTENT = open(SSH_KEY,'r').read() fields = dict([ ('request', '10534'), ('key', 'Aw7pItGVKFuZ_FOR3U8VFQ=='), ('ssh_keys', SSH_KEY_CONTENT) ]) r = requests.post(UPLOAD_URL, params=fields) print(r.text) .. code-block:: bash REQUEST_SFTP_ACCESS_URL="https://upgrade.odoo.com/database/v1/request_sftp_access" SSH_KEYS=/path/to/your/authorized_keys KEY="Aw7pItGVKFuZ_FOR3U8VFQ==" REQUEST_ID="10534" URL_PARAMS="key=${KEY}&request=${REQUEST_ID}" curl -sS "${REQUEST_SFTP_ACCESS_URL}?${URL_PARAMS}" -F ssh_keys=@${SSH_KEYS} > request_sftp_result.json # check for failures failures=$(cat request_sftp_result.json | jq -r '.failures[]') if [ "$failures" != "" ]; then echo $failures | jq -r '.' exit 1 fi ``failures`` '''''''''''' The list of errors. See :ref:`failures ` for an explanation about the JSON dictionary returned in case of failure. ``request`` ''''''''''' If the call is successful, the value associated to the *request* key will be a dictionary containing your SFTP connexion parameters: * ``hostname``: the host address to connect to * ``sftp_port``: the port to connect to * ``sftp_user``: the SFTP user to use for connecting * ``shared_file``: the filename you need to use (identical to the ``filename`` value you have used when creating the request in the :ref:`create method `.) * ``request_id``: the related upgrade request id (only informative, ,not required for the connection) * ``sample_command``: a sample command using the 'sftp' client You should normally be able to connect using the sample command as is. You will only have access to the ``shared_file``. No other files will be accessible and you will not be able to create new files in your shared environment on the SFTP server. Using the 'sftp' client +++++++++++++++++++++++ Once you have successfully connected using your SFTP client, you can upload your database dump. Here is a sample session using the 'sftp' client: :: $ sftp -P 2200 user_10534@upgrade.odoo.com Connected to upgrade.odoo.com. sftp> put /path/to/openchs.70.cdump openchs.70.cdump Uploading /path/to/openchs.70.cdump to /openchs.70.cdump sftp> ls -l openchs.70.cdump -rw-rw-rw- 0 0 0 849920 Aug 30 15:58 openchs.70.cdump If your connection is interrupted, you can continue your file transfer using the ``-a`` command line switch: .. code-block:: text sftp> put -a /path/to/openchs.70.cdump openchs.70.cdump Resuming upload of /path/to/openchs.70.cdump to /openchs.70.cdump If you don't want to manually type the command and need to automate your database upgrade using a script, you can use a batch file or pipe your commands to 'sftp': :: echo "put /path/to/openchs.70.cdump openchs.70.cdump" | sftp -b - -P 2200 user_10534@upgrade.odoo.com The ``-b`` parameter takes a filename. If the filename is ``-``, it reads the commands from standard input. .. _upgrade-api-process-method: Asking to process your request ============================== This action ask the Upgrade Platform to process your database dump. The ``process`` method ---------------------- .. py:function:: https://upgrade.odoo.com/database/v1/process Process a database dump :param str key: (required) your private key :param str request: (required) your request id :return: request result :rtype: JSON dictionary The request id and the private key are obtained using the :ref:`create method ` The result is a JSON dictionary containing the list of ``failures``, which should be empty if everything went fine. .. rst-class:: setup doc-aside .. switcher:: .. code-block:: python import requests PROCESS_URL = "https://upgrade.odoo.com/database/v1/process" fields = dict([ ('request', '10534'), ('key', 'Aw7pItGVKFuZ_FOR3U8VFQ=='), ]) r = requests.get(PROCESS_URL, data=fields) print(r.text) .. code-block:: bash PROCESS_URL="https://upgrade.odoo.com/database/v1/process" KEY="Aw7pItGVKFuZ_FOR3U8VFQ==" REQUEST_ID="10534" URL_PARAMS="key=${KEY}&request=${REQUEST_ID}" curl -sS "${PROCESS_URL}?${URL_PARAMS}" .. _upgrade-api-skip-tests: Asking to skip the tests ========================= This action asks the Upgrade Platform to skip the tests for your request. If you don't want Odoo to test and validate the migration, you can bypass the testing stage and directly get the migrated dump. The ``skip_test`` method ------------------------ .. py:function:: https://upgrade.odoo.com/database/v1/skip_test Skip the tests, deliver the upgraded dump, and set the state to 'delivered' :param str key: (required) your private key :param str request: (required) your request id :return: request result :rtype: JSON dictionary The request id and the private key are obtained using the :ref:`create method ` The result is a JSON dictionary containing the list of ``failures``, which should be empty if everything went fine. .. rst-class:: setup doc-aside .. switcher:: .. code-block:: python import requests PROCESS_URL = "https://upgrade.odoo.com/database/v1/skip_test" fields = dict([ ('request', '10534'), ('key', 'Aw7pItGVKFuZ_FOR3U8VFQ=='), ]) r = requests.get(PROCESS_URL, data=fields) print(r.text) .. code-block:: bash PROCESS_URL="https://upgrade.odoo.com/database/v1/skip_test" KEY="Aw7pItGVKFuZ_FOR3U8VFQ==" REQUEST_ID="10534" URL_PARAMS="key=${KEY}&request=${REQUEST_ID}" curl -sS "${PROCESS_URL}?${URL_PARAMS}" .. _upgrade-api-status-method: Obtaining your request status ============================= This action ask the status of your database upgrade request. The ``status`` method --------------------- .. py:function:: https://upgrade.odoo.com/database/v1/status Ask the status of a database upgrade request :param str key: (required) your private key :param str request: (required) your request id :return: request result :rtype: JSON dictionary The request id and the private key are obtained using the :ref:`create method ` The result is a JSON dictionary containing various information about your database upgrade request. .. rst-class:: setup doc-aside .. switcher:: .. code-block:: python import requests PROCESS_URL = "https://upgrade.odoo.com/database/v1/status" fields = dict([ ('request', '10534'), ('key', 'Aw7pItGVKFuZ_FOR3U8VFQ=='), ]) r = requests.get(PROCESS_URL, data=fields) print(r.text) .. code-block:: bash STATUS_URL="https://upgrade.odoo.com/database/v1/status" KEY="Aw7pItGVKFuZ_FOR3U8VFQ==" REQUEST_ID="10534" URL_PARAMS="key=${KEY}&request=${REQUEST_ID}" curl -sS "${STATUS_URL}?${URL_PARAMS}" Sample output ------------- The ``request`` key contains various useful information about your request: ``id`` the request id ``key`` your private key ``email`` the email address you supplied when creating the request ``target`` the target Odoo version you supplied when creating the request ``aim`` the purpose (test, production) of your database upgrade request you supplied when creating the request ``filename`` the filename you supplied when creating the request ``timezone`` the timezone you supplied when creating the request ``state`` the state of your request ``issue_stage`` the stage of the issue we have create on Odoo main server ``issue`` the id of the issue we have create on Odoo main server ``status_url`` the URL to access your database upgrade request html page ``notes_url`` the URL to get the notes about your database upgrade ``original_sql_url`` the URL used to get your uploaded (not upgraded) database as an SQL stream ``original_dump_url`` the URL used to get your uploaded (not upgraded) database as an archive file ``upgraded_sql_url`` the URL used to get your upgraded database as an SQL stream ``upgraded_dump_url`` the URL used to get your upgraded database as an archive file ``modules_url`` the URL used to get your custom modules ``filesize`` the size of your uploaded database file ``database_uuid`` the Unique ID of your database ``created_at`` the date when you created the request ``estimated_time`` an estimation of the time it takes to upgrade your database ``processed_at`` time when your database upgrade was started ``elapsed`` the time it takes to upgrade your database ``filestore`` your attachments were converted to the filestore ``customer_message`` an important message related to your request ``database_version`` the guessed Odoo version of your uploaded (not upgraded) database ``postgresql`` the guessed Postgresql version of your uploaded (not upgraded) database ``compressions`` the compression methods used by your uploaded database .. rst-class:: setup doc-aside .. switcher:: .. code-block:: json { "failures": [], "request": { "id": 10534, "key": "Aw7pItGVKFuZ_FOR3U8VFQ==", "email": "john.doe@example.com", "target": "12.0", "aim": "test", "filename": "db_name.dump", "timezone": null, "state": "draft", "issue_stage": "new", "issue": 648398, "status_url": "https://upgrade.odoo.com/database/eu1/10534/Aw7pItGVKFuZ_FOR3U8VFQ==/status", "notes_url": "https://upgrade.odoo.com/database/eu1/10534/Aw7pItGVKFuZ_FOR3U8VFQ==/upgraded/notes", "original_sql_url": "https://upgrade.odoo.com/database/eu1/10534/Aw7pItGVKFuZ_FOR3U8VFQ==/original/sql", "original_dump_url": "https://upgrade.odoo.com/database/eu1/10534/Aw7pItGVKFuZ_FOR3U8VFQ==/original/archive", "upgraded_sql_url": "https://upgrade.odoo.com/database/eu1/10534/Aw7pItGVKFuZ_FOR3U8VFQ==/upgraded/sql", "upgraded_dump_url": "https://upgrade.odoo.com/database/eu1/10534/Aw7pItGVKFuZ_FOR3U8VFQ==/upgraded/archive", "modules_url": "https://upgrade.odoo.com/database/eu1/10534/Aw7pItGVKFuZ_FOR3U8VFQ==/modules/archive", "filesize": "912.99 Kb", "database_uuid": null, "created_at": "2018-09-09 07:13:49", "estimated_time": null, "processed_at": null, "elapsed": "00:00", "filestore": false, "customer_message": null, "database_version": null, "postgresql": "9.4", "compressions": [ "pgdmp_custom", "sql" ] } } .. _upgrade-api-download-method: Downloading your database dump ============================== Beside downloading your migrated database using the URL provided by the :ref:`status method `, you can also use the SFTP protocol as described in the :ref:`request_sftp_access method ` The diffence is that you'll only be able to download the migrated database. No uploading will be possible. Your database upgrade request should be in the ``done`` state. Once you have successfully connected using your SFTP client, you can download your database dump. Here is a sample session using the 'sftp' client: :: $ sftp -P 2200 user_10534@upgrade.odoo.com Connected to upgrade.odoo.com. sftp> get upgraded_openchs.70.cdump /path/to/upgraded_openchs.70.cdump Downloading /upgraded_openchs.70.cdump to /path/to/upgraded_openchs.70.cdump