Skip to content

Commit 091a9ed

Browse files
committed
build(docker): upgrade to Ubuntu 24.04 and Python 3.12 (#692)
Closes reanahub/reana#808
1 parent c1b4b71 commit 091a9ed

File tree

12 files changed

+229
-205
lines changed

12 files changed

+229
-205
lines changed

.github/workflows/ci.yml

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ on: [push, pull_request]
1010

1111
jobs:
1212
lint-commitlint:
13-
runs-on: ubuntu-20.04
13+
runs-on: ubuntu-24.04
1414
steps:
1515
- name: Checkout
1616
uses: actions/checkout@v4
@@ -36,7 +36,7 @@ jobs:
3636
./run-tests.sh --check-commitlint ${{ github.event.pull_request.head.sha }}~${{ github.event.pull_request.commits }} ${{ github.event.pull_request.head.sha }} ${{ github.event.pull_request.number }}
3737
3838
lint-shellcheck:
39-
runs-on: ubuntu-20.04
39+
runs-on: ubuntu-24.04
4040
steps:
4141
- name: Checkout
4242
uses: actions/checkout@v4
@@ -47,79 +47,79 @@ jobs:
4747
./run-tests.sh --check-shellcheck
4848
4949
lint-black:
50-
runs-on: ubuntu-20.04
50+
runs-on: ubuntu-24.04
5151
steps:
5252
- name: Checkout
5353
uses: actions/checkout@v4
5454

5555
- name: Setup Python
5656
uses: actions/setup-python@v5
5757
with:
58-
python-version: "3.8"
58+
python-version: "3.12"
5959

6060
- name: Check Python code formatting
6161
run: |
6262
pip install black
6363
./run-tests.sh --check-black
6464
6565
lint-flake8:
66-
runs-on: ubuntu-20.04
66+
runs-on: ubuntu-24.04
6767
steps:
6868
- name: Checkout
6969
uses: actions/checkout@v4
7070

7171
- name: Setup Python
7272
uses: actions/setup-python@v5
7373
with:
74-
python-version: "3.8"
74+
python-version: "3.12"
7575

7676
- name: Check compliance with pep8, pyflakes and circular complexity
7777
run: |
7878
pip install flake8
7979
./run-tests.sh --check-flake8
8080
8181
lint-pydocstyle:
82-
runs-on: ubuntu-20.04
82+
runs-on: ubuntu-24.04
8383
steps:
8484
- name: Checkout
8585
uses: actions/checkout@v4
8686

8787
- name: Setup Python
8888
uses: actions/setup-python@v5
8989
with:
90-
python-version: "3.8"
90+
python-version: "3.12"
9191

9292
- name: Check compliance with Python docstring conventions
9393
run: |
9494
pip install pydocstyle
9595
./run-tests.sh --check-pydocstyle
9696
9797
lint-check-manifest:
98-
runs-on: ubuntu-20.04
98+
runs-on: ubuntu-24.04
9999
steps:
100100
- name: Checkout
101101
uses: actions/checkout@v4
102102

103103
- name: Setup Python
104104
uses: actions/setup-python@v5
105105
with:
106-
python-version: "3.8"
106+
python-version: "3.12"
107107

108108
- name: Check Python manifest completeness
109109
run: |
110110
pip install check-manifest
111111
./run-tests.sh --check-manifest
112112
113113
docs-sphinx:
114-
runs-on: ubuntu-20.04
114+
runs-on: ubuntu-24.04
115115
steps:
116116
- name: Checkout
117117
uses: actions/checkout@v4
118118

119119
- name: Setup Python
120120
uses: actions/setup-python@v5
121121
with:
122-
python-version: "3.8"
122+
python-version: "3.12"
123123

124124
- name: Install system dependencies
125125
run: |
@@ -135,16 +135,15 @@ jobs:
135135
run: ./run-tests.sh --check-sphinx
136136

137137
python-tests:
138-
runs-on: ubuntu-20.04
139-
138+
runs-on: ubuntu-24.04
140139
steps:
141140
- name: Checkout
142141
uses: actions/checkout@v4
143142

144143
- name: Setup Python
145144
uses: actions/setup-python@v5
146145
with:
147-
python-version: "3.8"
146+
python-version: "3.12"
148147

149148
- name: Install Python dependencies
150149
run: |
@@ -164,7 +163,7 @@ jobs:
164163
files: coverage.xml
165164

166165
lint-dockerfile:
167-
runs-on: ubuntu-20.04
166+
runs-on: ubuntu-24.04
168167
steps:
169168
- name: Checkout
170169
uses: actions/checkout@v4
@@ -173,7 +172,7 @@ jobs:
173172
run: ./run-tests.sh --check-dockerfile
174173

175174
docker-build:
176-
runs-on: ubuntu-20.04
175+
runs-on: ubuntu-24.04
177176
steps:
178177
- name: Checkout
179178
uses: actions/checkout@v4
@@ -182,7 +181,7 @@ jobs:
182181
run: ./run-tests.sh --check-docker-build
183182

184183
release-docker:
185-
runs-on: ubuntu-20.04
184+
runs-on: ubuntu-24.04
186185
if: >
187186
vars.RELEASE_DOCKER == 'true' &&
188187
github.event_name == 'push' &&

.readthedocs.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
version: 2
88

99
build:
10-
os: ubuntu-22.04
10+
os: ubuntu-24.04
1111
tools:
12-
python: "3.8"
12+
python: "3.12"
1313

1414
sphinx:
1515
configuration: docs/conf.py

Dockerfile

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,13 @@
55
# under the terms of the MIT License; see LICENSE file for more details.
66

77
# Use Ubuntu LTS base image
8-
FROM docker.io/library/ubuntu:20.04
8+
FROM docker.io/library/ubuntu:24.04
99

1010
# Use default answers in installation commands
1111
ENV DEBIAN_FRONTEND=noninteractive
1212

13-
# Use distutils provided by the standard Python library instead of the vendored one in
14-
# setuptools, so that editable installations are stored in the right directory.
15-
# See https://github.com/pypa/setuptools/issues/3301
16-
ENV SETUPTOOLS_USE_DISTUTILS=stdlib
13+
# Allow pip to install packages in the system site-packages dir
14+
ENV PIP_BREAK_SYSTEM_PACKAGES=true
1715

1816
# Prepare list of Python dependencies
1917
COPY requirements.txt /code/
@@ -27,17 +25,17 @@ RUN apt-get update -y && \
2725
libffi-dev \
2826
libpcre3 \
2927
libpcre3-dev \
30-
libpython3.8 \
28+
libpython3.12 \
3129
procps \
3230
python3-pip \
33-
python3.8 \
34-
python3.8-dev \
31+
python3.12 \
32+
python3.12-dev \
3533
vim-tiny && \
36-
pip install --no-cache-dir --upgrade pip 'setuptools<71' && \
34+
pip install --no-cache-dir --upgrade setuptools && \
3735
pip install --no-cache-dir -r /code/requirements.txt && \
3836
apt-get remove -y \
3937
gcc \
40-
python3.8-dev && \
38+
python3.12-dev && \
4139
apt-get autoremove -y && \
4240
apt-get clean && \
4341
rm -rf /var/lib/apt/lists/*
@@ -68,7 +66,7 @@ RUN if test -e modules/reana-commons; then \
6866
fi
6967

7068
# A quick fix to allow eduGAIN and social login users that wouldn't otherwise match Invenio username rules
71-
RUN sed -i 's|^username_regex = re.compile\(.*\)$|username_regex = re.compile("^\\S+$")|g' /usr/local/lib/python3.8/dist-packages/invenio_userprofiles/validators.py
69+
RUN sed -i 's|^username_regex = re.compile\(.*\)$|username_regex = re.compile("^\\S+$")|g' /usr/local/lib/python3.12/dist-packages/invenio_userprofiles/validators.py
7270

7371
# Check for any broken Python dependencies
7472
# hadolint ignore=DL3059

docs/openapi.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@
77
"paths": {
88
"/account/settings/linkedaccounts/": {},
99
"/account/settings/linkedaccounts/static/{filename}": {},
10-
"/account/settings/login": {},
11-
"/account/settings/security/": {},
12-
"/account/settings/sessions/revoke/": {},
13-
"/account/settings/static/{filename}": {},
1410
"/api/config": {
1511
"get": {
1612
"description": "This resource provides configuration needed by Reana-UI.",
@@ -4543,6 +4539,7 @@
45434539
"/oauth/disconnect/{remote_app}/": {},
45444540
"/oauth/login": {},
45454541
"/oauth/login/{remote_app}/": {},
4542+
"/oauth/logout": {},
45464543
"/oauth/signup/{remote_app}/": {},
45474544
"/oauth/static/{filename}": {},
45484545
"/signin": {},

reana_server/app.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
# -*- coding: utf-8 -*-
22
#
33
# This file is part of REANA.
4-
# Copyright (C) 2017, 2018, 2019, 2020, 2021 CERN.
4+
# Copyright (C) 2017, 2018, 2019, 2020, 2021, 2024 CERN.
55
#
66
# REANA is free software; you can redistribute it and/or modify it
77
# under the terms of the MIT License; see LICENSE file for more details.
88

99
"""Main entrypoint for REANA-Server."""
1010

11-
from reana_server.factory import create_app
11+
from invenio_app.factory import create_app
1212

1313
# Needed for flask.with_appcontext decorator to work.
14+
#
15+
# Note that this is the full Flask app including all the necessary Invenio modules.
16+
# See `factory.py` for more details.
1417
app = create_app()
1518

1619
if __name__ == "__main__":

reana_server/ext.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,13 @@ def handle_args_validation_error(error: UnprocessableEntity):
5353

5454

5555
class REANA(object):
56-
"""REANA Invenio app."""
56+
"""REANA Invenio app.
57+
58+
This is used to initialise REANA as a Flask/Invenio extension,
59+
and this is used in production.
60+
61+
See the docsting of `reana_server/factory.py` for more details.
62+
"""
5763

5864
def __init__(self, app=None):
5965
"""Extension initialization."""

reana_server/factory.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# -*- coding: utf-8 -*-
22
#
33
# This file is part of REANA.
4-
# Copyright (C) 2017, 2018, 2019, 2020, 2021, 2022 CERN.
4+
# Copyright (C) 2017, 2018, 2019, 2020, 2021, 2022, 2024 CERN.
55
#
66
# REANA is free software; you can redistribute it and/or modify it
77
# under the terms of the MIT License; see LICENSE file for more details.
@@ -11,11 +11,10 @@
1111
import logging
1212

1313
from flask import Flask, current_app
14-
from flask_babelex import Babel
14+
from invenio_i18n import Babel, InvenioI18N
1515
from flask_menu import Menu as FlaskMenu
1616
from flask_oauthlib.client import OAuth as FlaskOAuth
1717
from invenio_accounts import InvenioAccounts
18-
from invenio_accounts.views import blueprint as blueprint_user
1918
from invenio_db import InvenioDB
2019
from invenio_oauthclient import InvenioOAuthClient
2120
from invenio_oauthclient.views.client import blueprint as blueprint_client
@@ -24,8 +23,23 @@
2423
from reana_db.database import Session
2524

2625

27-
def create_app(config_mapping=None):
28-
"""REANA Server application factory."""
26+
def create_minimal_app(config_mapping=None):
27+
"""REANA Server application factory.
28+
29+
Create a minimal Flask app containing all of REANA's endpoints and the needed
30+
Invenio modules. Use `invenio_app.factory.create_app` the create the full Invenio
31+
app that is also used in production or when invoking `invenio run`.
32+
33+
This method is used to create the Flask app in the tests and in the
34+
`generate_openapi_spec.py` script.
35+
36+
In general, this is how Flask apps are created:
37+
- When running in debug mode, `invenio run ...` is invoked. This calls `invenio_app.factory.create_app`.
38+
- When running in production mode, `uwsgi` is used, and the module configured is `invenio_app.wsgi:application`. This calls `invenio_app.factory.create_app`.
39+
- When running `flask reana-admin` commands, flask auto-detects the app present in `app.py`, which is created with `invenio_app.factory.create_app`.
40+
- When running the tests, `reana_server.factory.create_minimal_app` is called.
41+
- When running `generate_openapi_spec.py`, the app is created with `reana_server.factory.create_minimal_app`.
42+
"""
2943
logging.basicConfig(level=REANA_LOG_LEVEL, format=REANA_LOG_FORMAT, force=True)
3044
app = Flask(__name__)
3145
app.config.from_object("reana_server.config")
@@ -35,15 +49,16 @@ def create_app(config_mapping=None):
3549

3650
app.session = Session
3751

52+
# Inspired from https://github.com/inveniosoftware/invenio-accounts/blob/345abfc2d3bf4af0be898a1b4ee1fe45edd16053/tests/conftest.py#L66
3853
Babel(app)
3954
FlaskMenu(app)
4055
InvenioDB(app)
56+
InvenioI18N(app)
4157
InvenioAccounts(app)
4258
FlaskOAuth(app)
4359
InvenioOAuthClient(app)
4460

4561
# Register Invenio OAuth endpoints
46-
app.register_blueprint(blueprint_user)
4762
app.register_blueprint(blueprint_client)
4863
app.register_blueprint(blueprint_settings)
4964

0 commit comments

Comments
 (0)