Skip to content

Commit

Permalink
Merge pull request #1897 from Chris-Peterson444/autoinstall-exception-F…
Browse files Browse the repository at this point in the history
…R-6293

AutoinstallError exception
  • Loading branch information
Chris-Peterson444 authored Feb 6, 2024
2 parents fa8cc03 + 24de248 commit 48e5f9c
Show file tree
Hide file tree
Showing 30 changed files with 686 additions and 8 deletions.
6 changes: 6 additions & 0 deletions autoinstall-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
"minimum": 1,
"maximum": 1
},
"interactive-sections": {
"type": "array",
"items": {
"type": "string"
}
},
"early-commands": {
"type": "array",
"items": {
Expand Down
6 changes: 6 additions & 0 deletions autoinstall-system-setup-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
"minimum": 1,
"maximum": 1
},
"interactive-sections": {
"type": "array",
"items": {
"type": "string"
}
},
"early-commands": {
"type": "array",
"items": {
Expand Down
31 changes: 31 additions & 0 deletions subiquity/server/autoinstall.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2024 Canonical, Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# 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/>.
import logging

log = logging.getLogger("subiquity.server.autoinstall")


class AutoinstallError(Exception):
pass


class AutoinstallValidationError(AutoinstallError):
def __init__(
self,
owner: str,
):
self.message = f"Malformed autoinstall in {owner!r} section"
self.owner = owner
super().__init__(self.message)
18 changes: 17 additions & 1 deletion subiquity/server/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
from typing import Any, Optional

import jsonschema
from jsonschema.exceptions import ValidationError

from subiquity.common.api.server import bind
from subiquity.server.autoinstall import AutoinstallValidationError
from subiquity.server.types import InstallerChannels
from subiquitycore.context import with_context
from subiquitycore.controller import BaseController
Expand Down Expand Up @@ -54,6 +56,19 @@ async def _confirmed(self):
await self.configured()
self._active = False

def validate_autoinstall(self, ai_data: dict) -> None:
try:
jsonschema.validate(ai_data, self.autoinstall_schema)

except ValidationError as original_exception:
section = self.autoinstall_key

new_exception: AutoinstallValidationError = AutoinstallValidationError(
section,
)

raise new_exception from original_exception

def setup_autoinstall(self):
if not self.app.autoinstall_config:
return
Expand All @@ -72,7 +87,8 @@ def setup_autoinstall(self):
ai_data = self.autoinstall_default

if ai_data is not None and self.autoinstall_schema is not None:
jsonschema.validate(ai_data, self.autoinstall_schema)
self.validate_autoinstall(ai_data)

self.load_autoinstall_data(ai_data)

def load_autoinstall_data(self, data):
Expand Down
31 changes: 31 additions & 0 deletions subiquity/server/controllers/tests/test_cmdlist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2024 Canonical, Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# 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/>.

import jsonschema
from jsonschema.validators import validator_for

from subiquity.server.controllers.cmdlist import CmdListController
from subiquitycore.tests import SubiTestCase


class TestCmdListController(SubiTestCase):
def test_valid_schema(self):
"""Test that the expected autoinstall JSON schema is valid"""

JsonValidator: jsonschema.protocols.Validator = validator_for(
CmdListController.autoinstall_schema
)

JsonValidator.check_schema(CmdListController.autoinstall_schema)
31 changes: 31 additions & 0 deletions subiquity/server/controllers/tests/test_codecs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2024 Canonical, Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# 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/>.

import jsonschema
from jsonschema.validators import validator_for

from subiquity.server.controllers.codecs import CodecsController
from subiquitycore.tests import SubiTestCase


class TestCodecsController(SubiTestCase):
def test_valid_schema(self):
"""Test that the expected autoinstall JSON schema is valid"""

JsonValidator: jsonschema.protocols.Validator = validator_for(
CodecsController.autoinstall_schema
)

JsonValidator.check_schema(CodecsController.autoinstall_schema)
31 changes: 31 additions & 0 deletions subiquity/server/controllers/tests/test_debconf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2024 Canonical, Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# 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/>.

import jsonschema
from jsonschema.validators import validator_for

from subiquity.server.controllers.debconf import DebconfController
from subiquitycore.tests import SubiTestCase


class TestDebconfController(SubiTestCase):
def test_valid_schema(self):
"""Test that the expected autoinstall JSON schema is valid"""

JsonValidator: jsonschema.protocols.Validator = validator_for(
DebconfController.autoinstall_schema
)

JsonValidator.check_schema(DebconfController.autoinstall_schema)
31 changes: 31 additions & 0 deletions subiquity/server/controllers/tests/test_drivers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2024 Canonical, Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# 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/>.

import jsonschema
from jsonschema.validators import validator_for

from subiquity.server.controllers.drivers import DriversController
from subiquitycore.tests import SubiTestCase


class TestDriversController(SubiTestCase):
def test_valid_schema(self):
"""Test that the expected autoinstall JSON schema is valid"""

JsonValidator: jsonschema.protocols.Validator = validator_for(
DriversController.autoinstall_schema
)

JsonValidator.check_schema(DriversController.autoinstall_schema)
11 changes: 11 additions & 0 deletions subiquity/server/controllers/tests/test_filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
import uuid
from unittest import IsolatedAsyncioTestCase, mock

import jsonschema
from curtin.commands.extract import TrivialSourceHandler
from jsonschema.validators import validator_for

from subiquity.common.filesystem import gaps, labels
from subiquity.common.filesystem.actions import DeviceAction
Expand Down Expand Up @@ -399,6 +401,15 @@ async def test_examine_systems(self):
self.assertEqual(len(self.fsc._variation_info), 1)
self.assertEqual(self.fsc._variation_info["default"].name, "default")

def test_valid_schema(self):
"""Test that the expected autoinstall JSON schema is valid"""

JsonValidator: jsonschema.protocols.Validator = validator_for(
FilesystemController.autoinstall_schema
)

JsonValidator.check_schema(FilesystemController.autoinstall_schema)


class TestGuided(IsolatedAsyncioTestCase):
boot_expectations = [
Expand Down
31 changes: 31 additions & 0 deletions subiquity/server/controllers/tests/test_identity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2024 Canonical, Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# 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/>.

import jsonschema
from jsonschema.validators import validator_for

from subiquity.server.controllers.identity import IdentityController
from subiquitycore.tests import SubiTestCase


class TestIdentityController(SubiTestCase):
def test_valid_schema(self):
"""Test that the expected autoinstall JSON schema is valid"""

JsonValidator: jsonschema.protocols.Validator = validator_for(
IdentityController.autoinstall_schema
)

JsonValidator.check_schema(IdentityController.autoinstall_schema)
13 changes: 13 additions & 0 deletions subiquity/server/controllers/tests/test_keyboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
import unittest
from unittest.mock import Mock, patch

import jsonschema
from jsonschema.validators import validator_for

from subiquity.common.types import KeyboardSetting
from subiquity.models.keyboard import KeyboardModel
from subiquity.server.controllers.keyboard import KeyboardController
Expand All @@ -29,6 +32,16 @@ class opts:
dry_run = True


class TestKeyboardController(SubiTestCase):
def test_valid_schema(self):
"""Test that the expected autoinstall JSON schema is valid"""

JsonValidator: jsonschema.protocols.Validator = validator_for(
KeyboardController.autoinstall_schema
)
JsonValidator.check_schema(KeyboardController.autoinstall_schema)


class TestSubiquityModel(SubiTestCase):
async def test_write_config(self):
os.environ["SUBIQUITY_REPLAY_TIMESCALE"] = "100"
Expand Down
31 changes: 31 additions & 0 deletions subiquity/server/controllers/tests/test_locale.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2024 Canonical, Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# 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/>.

import jsonschema
from jsonschema.validators import validator_for

from subiquity.server.controllers.locale import LocaleController
from subiquitycore.tests import SubiTestCase


class TestLocaleController(SubiTestCase):
def test_valid_schema(self):
"""Test that the expected autoinstall JSON schema is valid"""

JsonValidator: jsonschema.protocols.Validator = validator_for(
LocaleController.autoinstall_schema
)

JsonValidator.check_schema(LocaleController.autoinstall_schema)
10 changes: 10 additions & 0 deletions subiquity/server/controllers/tests/test_mirror.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from unittest import mock

import jsonschema
from jsonschema.validators import validator_for

from subiquity.common.types import MirrorSelectionFallback
from subiquity.models.mirror import MirrorModel
Expand Down Expand Up @@ -264,3 +265,12 @@ async def test_run_mirror_selection_or_fallback(self):
mock_fallback.assert_not_called()
await controller.run_mirror_selection_or_fallback(context=None)
mock_fallback.assert_called_once()

def test_valid_schema(self):
"""Test that the expected autoinstall JSON schema is valid"""

JsonValidator: jsonschema.protocols.Validator = validator_for(
MirrorController.autoinstall_schema
)

JsonValidator.check_schema(MirrorController.autoinstall_schema)
31 changes: 31 additions & 0 deletions subiquity/server/controllers/tests/test_network.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2024 Canonical, Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# 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/>.

import jsonschema
from jsonschema.validators import validator_for

from subiquity.server.controllers.network import NetworkController
from subiquitycore.tests import SubiTestCase


class TestNetworkController(SubiTestCase):
def test_valid_schema(self):
"""Test that the expected autoinstall JSON schema is valid"""

JsonValidator: jsonschema.protocols.Validator = validator_for(
NetworkController.autoinstall_schema
)

JsonValidator.check_schema(NetworkController.autoinstall_schema)
Loading

0 comments on commit 48e5f9c

Please sign in to comment.