ubuntu-pro: return number of packages and EOL ESM in /ubuntu_pro/info
We now rely on distro-info to find out the EOL ESM date on LTS releases. This information is meant to be shown on the Ubuntu Pro screens ; instead of hardcoded values. Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
This commit is contained in:
parent
7a5ff9e76a
commit
a42ea0a685
|
@ -27,6 +27,7 @@ python3-bson
|
||||||
python3-coverage
|
python3-coverage
|
||||||
python3-debian
|
python3-debian
|
||||||
python3-dev
|
python3-dev
|
||||||
|
python3-distro-info
|
||||||
python3-distutils-extra
|
python3-distutils-extra
|
||||||
python3-flake8
|
python3-flake8
|
||||||
python3-gi
|
python3-gi
|
||||||
|
|
|
@ -132,6 +132,7 @@ parts:
|
||||||
- python3-attr
|
- python3-attr
|
||||||
- python3-bson
|
- python3-bson
|
||||||
- python3-debian
|
- python3-debian
|
||||||
|
- python3-distro-info
|
||||||
- python3-jsonschema
|
- python3-jsonschema
|
||||||
- python3-minimal
|
- python3-minimal
|
||||||
- python3-oauthlib
|
- python3-oauthlib
|
||||||
|
|
|
@ -67,6 +67,7 @@ from subiquity.common.types import (
|
||||||
StorageResponseV2,
|
StorageResponseV2,
|
||||||
TimeZoneInfo,
|
TimeZoneInfo,
|
||||||
UbuntuProCheckTokenAnswer,
|
UbuntuProCheckTokenAnswer,
|
||||||
|
UbuntuProGeneralInfo,
|
||||||
UbuntuProInfo,
|
UbuntuProInfo,
|
||||||
UbuntuProResponse,
|
UbuntuProResponse,
|
||||||
UPCSInitiateResponse,
|
UPCSInitiateResponse,
|
||||||
|
@ -513,6 +514,10 @@ class API:
|
||||||
def POST() -> None:
|
def POST() -> None:
|
||||||
...
|
...
|
||||||
|
|
||||||
|
class info:
|
||||||
|
def GET() -> UbuntuProGeneralInfo:
|
||||||
|
...
|
||||||
|
|
||||||
class identity:
|
class identity:
|
||||||
def GET() -> IdentityData:
|
def GET() -> IdentityData:
|
||||||
...
|
...
|
||||||
|
|
|
@ -718,6 +718,13 @@ class UbuntuProCheckTokenStatus(enum.Enum):
|
||||||
UNKNOWN_ERROR = enum.auto()
|
UNKNOWN_ERROR = enum.auto()
|
||||||
|
|
||||||
|
|
||||||
|
@attr.s(auto_attribs=True)
|
||||||
|
class UbuntuProGeneralInfo:
|
||||||
|
eol_esm_year: Optional[int]
|
||||||
|
universe_packages: int
|
||||||
|
main_packages: int
|
||||||
|
|
||||||
|
|
||||||
@attr.s(auto_attribs=True)
|
@attr.s(auto_attribs=True)
|
||||||
class UPCSInitiateResponse:
|
class UPCSInitiateResponse:
|
||||||
"""Response to Ubuntu Pro contract selection initiate request."""
|
"""Response to Ubuntu Pro contract selection initiate request."""
|
||||||
|
|
|
@ -13,17 +13,20 @@
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import unittest
|
from unittest import mock
|
||||||
|
|
||||||
import jsonschema
|
import jsonschema
|
||||||
from jsonschema.validators import validator_for
|
from jsonschema.validators import validator_for
|
||||||
|
|
||||||
from subiquity.server.controllers.ubuntu_pro import UbuntuProController
|
from subiquity.server.controllers.ubuntu_pro import UbuntuProController
|
||||||
from subiquity.server.dryrun import DRConfig
|
from subiquity.server.dryrun import DRConfig
|
||||||
|
from subiquitycore.lsb_release import lsb_release_from_path
|
||||||
|
from subiquitycore.tests import SubiTestCase
|
||||||
from subiquitycore.tests.mocks import make_app
|
from subiquitycore.tests.mocks import make_app
|
||||||
|
from subiquitycore.tests.parameterized import parameterized
|
||||||
|
|
||||||
|
|
||||||
class TestUbuntuProController(unittest.TestCase):
|
class TestUbuntuProController(SubiTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
app = make_app()
|
app = make_app()
|
||||||
app.dr_cfg = DRConfig()
|
app.dr_cfg = DRConfig()
|
||||||
|
@ -45,3 +48,32 @@ class TestUbuntuProController(unittest.TestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
JsonValidator.check_schema(UbuntuProController.autoinstall_schema)
|
JsonValidator.check_schema(UbuntuProController.autoinstall_schema)
|
||||||
|
|
||||||
|
@parameterized.expand(
|
||||||
|
[
|
||||||
|
("focal", 23000, 2300, 2030),
|
||||||
|
("impish", 23000, 2300, None),
|
||||||
|
("jammy", 23000, 2300, 2032),
|
||||||
|
("noble", 23000, 2300, 2034),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
async def test_info_GET__series(
|
||||||
|
self, series: str, universe_pkgs: int, main_pkgs: int, esm_eol_year: int | None
|
||||||
|
):
|
||||||
|
def fake_lsb_release(*args, **kwargs):
|
||||||
|
return lsb_release_from_path(f"examples/lsb-release-{series}")
|
||||||
|
|
||||||
|
with mock.patch(
|
||||||
|
"subiquity.server.controllers.ubuntu_pro.lsb_release",
|
||||||
|
wraps=fake_lsb_release,
|
||||||
|
) as m_lsb_release:
|
||||||
|
info = await self.controller.info_GET()
|
||||||
|
|
||||||
|
m_lsb_release.assert_called_once()
|
||||||
|
|
||||||
|
self.assertEqual(universe_pkgs, info.universe_packages)
|
||||||
|
self.assertEqual(main_pkgs, info.main_packages)
|
||||||
|
if esm_eol_year is not None:
|
||||||
|
self.assertEqual(esm_eol_year, info.eol_esm_year)
|
||||||
|
else:
|
||||||
|
self.assertIsNone(info.eol_esm_year)
|
||||||
|
|
|
@ -19,10 +19,13 @@ import logging
|
||||||
import os
|
import os
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
import distro_info
|
||||||
|
|
||||||
from subiquity.common.apidef import API
|
from subiquity.common.apidef import API
|
||||||
from subiquity.common.types import (
|
from subiquity.common.types import (
|
||||||
UbuntuProCheckTokenAnswer,
|
UbuntuProCheckTokenAnswer,
|
||||||
UbuntuProCheckTokenStatus,
|
UbuntuProCheckTokenStatus,
|
||||||
|
UbuntuProGeneralInfo,
|
||||||
UbuntuProInfo,
|
UbuntuProInfo,
|
||||||
UbuntuProResponse,
|
UbuntuProResponse,
|
||||||
UPCSInitiateResponse,
|
UPCSInitiateResponse,
|
||||||
|
@ -40,6 +43,7 @@ from subiquity.server.ubuntu_advantage import (
|
||||||
UAInterface,
|
UAInterface,
|
||||||
UAInterfaceStrategy,
|
UAInterfaceStrategy,
|
||||||
)
|
)
|
||||||
|
from subiquitycore.lsb_release import lsb_release
|
||||||
|
|
||||||
log = logging.getLogger("subiquity.server.controllers.ubuntu_pro")
|
log = logging.getLogger("subiquity.server.controllers.ubuntu_pro")
|
||||||
|
|
||||||
|
@ -199,3 +203,27 @@ class UbuntuProController(SubiquityController):
|
||||||
|
|
||||||
self.cs.cancel()
|
self.cs.cancel()
|
||||||
self.cs = None
|
self.cs = None
|
||||||
|
|
||||||
|
async def info_GET(self) -> UbuntuProGeneralInfo:
|
||||||
|
# Currently the number of packages is hard-coded.
|
||||||
|
main_packages = 2300
|
||||||
|
universe_packages = 23000
|
||||||
|
eol_esm_year: Optional[int] = None
|
||||||
|
|
||||||
|
series = lsb_release(dry_run=self.app.opts.dry_run)["codename"]
|
||||||
|
|
||||||
|
for release in distro_info.UbuntuDistroInfo()._releases:
|
||||||
|
if release.series == series:
|
||||||
|
try:
|
||||||
|
eol_esm_year = release.eol_esm.year
|
||||||
|
except AttributeError:
|
||||||
|
log.warning("series %s does not have an ESM EOL date", series)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
log.warning("could not find distro info for %s", series)
|
||||||
|
|
||||||
|
return UbuntuProGeneralInfo(
|
||||||
|
eol_esm_year=eol_esm_year,
|
||||||
|
main_packages=main_packages,
|
||||||
|
universe_packages=universe_packages,
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue