Merge pull request #1897 from Chris-Peterson444/autoinstall-exception-FR-6293
AutoinstallError exception
This commit is contained in:
commit
48e5f9c616
|
@ -6,6 +6,12 @@
|
||||||
"minimum": 1,
|
"minimum": 1,
|
||||||
"maximum": 1
|
"maximum": 1
|
||||||
},
|
},
|
||||||
|
"interactive-sections": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
"early-commands": {
|
"early-commands": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
|
|
|
@ -6,6 +6,12 @@
|
||||||
"minimum": 1,
|
"minimum": 1,
|
||||||
"maximum": 1
|
"maximum": 1
|
||||||
},
|
},
|
||||||
|
"interactive-sections": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
"early-commands": {
|
"early-commands": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
|
|
|
@ -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)
|
|
@ -19,8 +19,10 @@ import os
|
||||||
from typing import Any, Optional
|
from typing import Any, Optional
|
||||||
|
|
||||||
import jsonschema
|
import jsonschema
|
||||||
|
from jsonschema.exceptions import ValidationError
|
||||||
|
|
||||||
from subiquity.common.api.server import bind
|
from subiquity.common.api.server import bind
|
||||||
|
from subiquity.server.autoinstall import AutoinstallValidationError
|
||||||
from subiquity.server.types import InstallerChannels
|
from subiquity.server.types import InstallerChannels
|
||||||
from subiquitycore.context import with_context
|
from subiquitycore.context import with_context
|
||||||
from subiquitycore.controller import BaseController
|
from subiquitycore.controller import BaseController
|
||||||
|
@ -54,6 +56,19 @@ class SubiquityController(BaseController):
|
||||||
await self.configured()
|
await self.configured()
|
||||||
self._active = False
|
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):
|
def setup_autoinstall(self):
|
||||||
if not self.app.autoinstall_config:
|
if not self.app.autoinstall_config:
|
||||||
return
|
return
|
||||||
|
@ -72,7 +87,8 @@ class SubiquityController(BaseController):
|
||||||
ai_data = self.autoinstall_default
|
ai_data = self.autoinstall_default
|
||||||
|
|
||||||
if ai_data is not None and self.autoinstall_schema is not None:
|
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)
|
self.load_autoinstall_data(ai_data)
|
||||||
|
|
||||||
def load_autoinstall_data(self, data):
|
def load_autoinstall_data(self, data):
|
||||||
|
|
|
@ -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)
|
|
@ -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)
|
|
@ -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)
|
|
@ -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)
|
|
@ -18,7 +18,9 @@ import subprocess
|
||||||
import uuid
|
import uuid
|
||||||
from unittest import IsolatedAsyncioTestCase, mock
|
from unittest import IsolatedAsyncioTestCase, mock
|
||||||
|
|
||||||
|
import jsonschema
|
||||||
from curtin.commands.extract import TrivialSourceHandler
|
from curtin.commands.extract import TrivialSourceHandler
|
||||||
|
from jsonschema.validators import validator_for
|
||||||
|
|
||||||
from subiquity.common.filesystem import gaps, labels
|
from subiquity.common.filesystem import gaps, labels
|
||||||
from subiquity.common.filesystem.actions import DeviceAction
|
from subiquity.common.filesystem.actions import DeviceAction
|
||||||
|
@ -399,6 +401,15 @@ class TestSubiquityControllerFilesystem(IsolatedAsyncioTestCase):
|
||||||
self.assertEqual(len(self.fsc._variation_info), 1)
|
self.assertEqual(len(self.fsc._variation_info), 1)
|
||||||
self.assertEqual(self.fsc._variation_info["default"].name, "default")
|
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):
|
class TestGuided(IsolatedAsyncioTestCase):
|
||||||
boot_expectations = [
|
boot_expectations = [
|
||||||
|
|
|
@ -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)
|
|
@ -17,6 +17,9 @@ import os
|
||||||
import unittest
|
import unittest
|
||||||
from unittest.mock import Mock, patch
|
from unittest.mock import Mock, patch
|
||||||
|
|
||||||
|
import jsonschema
|
||||||
|
from jsonschema.validators import validator_for
|
||||||
|
|
||||||
from subiquity.common.types import KeyboardSetting
|
from subiquity.common.types import KeyboardSetting
|
||||||
from subiquity.models.keyboard import KeyboardModel
|
from subiquity.models.keyboard import KeyboardModel
|
||||||
from subiquity.server.controllers.keyboard import KeyboardController
|
from subiquity.server.controllers.keyboard import KeyboardController
|
||||||
|
@ -29,6 +32,16 @@ class opts:
|
||||||
dry_run = True
|
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):
|
class TestSubiquityModel(SubiTestCase):
|
||||||
async def test_write_config(self):
|
async def test_write_config(self):
|
||||||
os.environ["SUBIQUITY_REPLAY_TIMESCALE"] = "100"
|
os.environ["SUBIQUITY_REPLAY_TIMESCALE"] = "100"
|
||||||
|
|
|
@ -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)
|
|
@ -19,6 +19,7 @@ import unittest
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
import jsonschema
|
import jsonschema
|
||||||
|
from jsonschema.validators import validator_for
|
||||||
|
|
||||||
from subiquity.common.types import MirrorSelectionFallback
|
from subiquity.common.types import MirrorSelectionFallback
|
||||||
from subiquity.models.mirror import MirrorModel
|
from subiquity.models.mirror import MirrorModel
|
||||||
|
@ -264,3 +265,12 @@ class TestMirrorController(unittest.IsolatedAsyncioTestCase):
|
||||||
mock_fallback.assert_not_called()
|
mock_fallback.assert_not_called()
|
||||||
await controller.run_mirror_selection_or_fallback(context=None)
|
await controller.run_mirror_selection_or_fallback(context=None)
|
||||||
mock_fallback.assert_called_once()
|
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)
|
||||||
|
|
|
@ -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)
|
|
@ -16,6 +16,9 @@
|
||||||
import subprocess
|
import subprocess
|
||||||
from unittest.mock import Mock, patch
|
from unittest.mock import Mock, patch
|
||||||
|
|
||||||
|
import jsonschema
|
||||||
|
from jsonschema.validators import validator_for
|
||||||
|
|
||||||
from subiquity.server.controllers.oem import OEMController
|
from subiquity.server.controllers.oem import OEMController
|
||||||
from subiquitycore.tests import SubiTestCase
|
from subiquitycore.tests import SubiTestCase
|
||||||
from subiquitycore.tests.mocks import make_app
|
from subiquitycore.tests.mocks import make_app
|
||||||
|
@ -110,3 +113,12 @@ Ubuntu-Oem-Kernel-Flavour: oem
|
||||||
"oem-sutton-balint-meta", context=None, overlay=Mock()
|
"oem-sutton-balint-meta", context=None, overlay=Mock()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_valid_schema(self):
|
||||||
|
"""Test that the expected autoinstall JSON schema is valid"""
|
||||||
|
|
||||||
|
JsonValidator: jsonschema.protocols.Validator = validator_for(
|
||||||
|
OEMController.autoinstall_schema
|
||||||
|
)
|
||||||
|
|
||||||
|
JsonValidator.check_schema(OEMController.autoinstall_schema)
|
||||||
|
|
|
@ -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.package import PackageController
|
||||||
|
from subiquitycore.tests import SubiTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestPackageController(SubiTestCase):
|
||||||
|
def test_valid_schema(self):
|
||||||
|
"""Test that the expected autoinstall JSON schema is valid"""
|
||||||
|
|
||||||
|
JsonValidator: jsonschema.protocols.Validator = validator_for(
|
||||||
|
PackageController.autoinstall_schema
|
||||||
|
)
|
||||||
|
|
||||||
|
JsonValidator.check_schema(PackageController.autoinstall_schema)
|
|
@ -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.proxy import ProxyController
|
||||||
|
from subiquitycore.tests import SubiTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestProxyController(SubiTestCase):
|
||||||
|
def test_valid_schema(self):
|
||||||
|
"""Test that the expected autoinstall JSON schema is valid"""
|
||||||
|
|
||||||
|
JsonValidator: jsonschema.protocols.Validator = validator_for(
|
||||||
|
ProxyController.autoinstall_schema
|
||||||
|
)
|
||||||
|
|
||||||
|
JsonValidator.check_schema(ProxyController.autoinstall_schema)
|
|
@ -15,6 +15,9 @@
|
||||||
|
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
|
import jsonschema
|
||||||
|
from jsonschema.validators import validator_for
|
||||||
|
|
||||||
from subiquity.server import snapdapi
|
from subiquity.server import snapdapi
|
||||||
from subiquity.server.controllers import refresh as refresh_mod
|
from subiquity.server.controllers import refresh as refresh_mod
|
||||||
from subiquity.server.controllers.refresh import RefreshController, SnapChannelSource
|
from subiquity.server.controllers.refresh import RefreshController, SnapChannelSource
|
||||||
|
@ -99,3 +102,12 @@ class TestRefreshController(SubiTestCase):
|
||||||
await self.rc.configure_snapd(context=self.rc.context)
|
await self.rc.configure_snapd(context=self.rc.context)
|
||||||
|
|
||||||
paw.assert_not_called()
|
paw.assert_not_called()
|
||||||
|
|
||||||
|
def test_valid_schema(self):
|
||||||
|
"""Test that the expected autoinstall JSON schema is valid"""
|
||||||
|
|
||||||
|
JsonValidator: jsonschema.protocols.Validator = validator_for(
|
||||||
|
RefreshController.autoinstall_schema
|
||||||
|
)
|
||||||
|
|
||||||
|
JsonValidator.check_schema(RefreshController.autoinstall_schema)
|
||||||
|
|
|
@ -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.reporting import ReportingController
|
||||||
|
from subiquitycore.tests import SubiTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestReportingController(SubiTestCase):
|
||||||
|
def test_valid_schema(self):
|
||||||
|
"""Test that the expected autoinstall JSON schema is valid"""
|
||||||
|
|
||||||
|
JsonValidator: jsonschema.protocols.Validator = validator_for(
|
||||||
|
ReportingController.autoinstall_schema
|
||||||
|
)
|
||||||
|
|
||||||
|
JsonValidator.check_schema(ReportingController.autoinstall_schema)
|
|
@ -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.shutdown import ShutdownController
|
||||||
|
from subiquitycore.tests import SubiTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestShutdownController(SubiTestCase):
|
||||||
|
def test_valid_schema(self):
|
||||||
|
"""Test that the expected autoinstall JSON schema is valid"""
|
||||||
|
|
||||||
|
JsonValidator: jsonschema.protocols.Validator = validator_for(
|
||||||
|
ShutdownController.autoinstall_schema
|
||||||
|
)
|
||||||
|
|
||||||
|
JsonValidator.check_schema(ShutdownController.autoinstall_schema)
|
|
@ -16,13 +16,17 @@
|
||||||
import unittest
|
import unittest
|
||||||
from unittest.mock import AsyncMock
|
from unittest.mock import AsyncMock
|
||||||
|
|
||||||
|
import jsonschema
|
||||||
import requests
|
import requests
|
||||||
|
from jsonschema.validators import validator_for
|
||||||
|
|
||||||
from subiquity.models.snaplist import SnapListModel
|
from subiquity.models.snaplist import SnapListModel
|
||||||
from subiquity.server.controllers.snaplist import (
|
from subiquity.server.controllers.snaplist import (
|
||||||
SnapdSnapInfoLoader,
|
SnapdSnapInfoLoader,
|
||||||
|
SnapListController,
|
||||||
SnapListFetchError,
|
SnapListFetchError,
|
||||||
)
|
)
|
||||||
|
from subiquitycore.tests import SubiTestCase
|
||||||
from subiquitycore.tests.mocks import make_app
|
from subiquitycore.tests.mocks import make_app
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,3 +60,14 @@ class TestSnapdSnapInfoLoader(unittest.IsolatedAsyncioTestCase):
|
||||||
await self.loader.get_snap_list_task()
|
await self.loader.get_snap_list_task()
|
||||||
self.assertTrue(self.loader.fetch_list_completed())
|
self.assertTrue(self.loader.fetch_list_completed())
|
||||||
self.assertFalse(self.loader.fetch_list_failed())
|
self.assertFalse(self.loader.fetch_list_failed())
|
||||||
|
|
||||||
|
|
||||||
|
class TestSnapListController(SubiTestCase):
|
||||||
|
def test_valid_schema(self):
|
||||||
|
"""Test that the expected autoinstall JSON schema is valid"""
|
||||||
|
|
||||||
|
JsonValidator: jsonschema.protocols.Validator = validator_for(
|
||||||
|
SnapListController.autoinstall_schema
|
||||||
|
)
|
||||||
|
|
||||||
|
JsonValidator.check_schema(SnapListController.autoinstall_schema)
|
||||||
|
|
|
@ -16,6 +16,9 @@
|
||||||
import unittest
|
import unittest
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
|
import jsonschema
|
||||||
|
from jsonschema.validators import validator_for
|
||||||
|
|
||||||
from subiquity.common.types import SSHFetchIdStatus, SSHIdentity
|
from subiquity.common.types import SSHFetchIdStatus, SSHIdentity
|
||||||
from subiquity.server.controllers.ssh import (
|
from subiquity.server.controllers.ssh import (
|
||||||
SSHController,
|
SSHController,
|
||||||
|
@ -116,3 +119,12 @@ class TestSSHController(unittest.IsolatedAsyncioTestCase):
|
||||||
self.assertEqual(response.status, SSHFetchIdStatus.FINGERPRINT_ERROR)
|
self.assertEqual(response.status, SSHFetchIdStatus.FINGERPRINT_ERROR)
|
||||||
self.assertEqual(response.error, stderr)
|
self.assertEqual(response.error, stderr)
|
||||||
self.assertIsNone(response.identities)
|
self.assertIsNone(response.identities)
|
||||||
|
|
||||||
|
def test_valid_schema(self):
|
||||||
|
"""Test that the expected autoinstall JSON schema is valid"""
|
||||||
|
|
||||||
|
JsonValidator: jsonschema.protocols.Validator = validator_for(
|
||||||
|
SSHController.autoinstall_schema
|
||||||
|
)
|
||||||
|
|
||||||
|
JsonValidator.check_schema(SSHController.autoinstall_schema)
|
||||||
|
|
|
@ -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.timezone import TimeZoneController
|
||||||
|
from subiquitycore.tests import SubiTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestTimeZoneController(SubiTestCase):
|
||||||
|
def test_valid_schema(self):
|
||||||
|
"""Test that the expected autoinstall JSON schema is valid"""
|
||||||
|
|
||||||
|
JsonValidator: jsonschema.protocols.Validator = validator_for(
|
||||||
|
TimeZoneController.autoinstall_schema
|
||||||
|
)
|
||||||
|
|
||||||
|
JsonValidator.check_schema(TimeZoneController.autoinstall_schema)
|
|
@ -15,6 +15,9 @@
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
import jsonschema
|
||||||
|
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.tests.mocks import make_app
|
from subiquitycore.tests.mocks import make_app
|
||||||
|
@ -33,3 +36,12 @@ class TestUbuntuProController(unittest.TestCase):
|
||||||
def test_deserialize(self):
|
def test_deserialize(self):
|
||||||
self.controller.deserialize("1A2B3C4D")
|
self.controller.deserialize("1A2B3C4D")
|
||||||
self.assertEqual(self.controller.model.token, "1A2B3C4D")
|
self.assertEqual(self.controller.model.token, "1A2B3C4D")
|
||||||
|
|
||||||
|
def test_valid_schema(self):
|
||||||
|
"""Test that the expected autoinstall JSON schema is valid"""
|
||||||
|
|
||||||
|
JsonValidator: jsonschema.protocols.Validator = validator_for(
|
||||||
|
UbuntuProController.autoinstall_schema
|
||||||
|
)
|
||||||
|
|
||||||
|
JsonValidator.check_schema(UbuntuProController.autoinstall_schema)
|
||||||
|
|
|
@ -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.updates import UpdatesController
|
||||||
|
from subiquitycore.tests import SubiTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestUpdatesController(SubiTestCase):
|
||||||
|
def test_valid_schema(self):
|
||||||
|
"""Test that the expected autoinstall JSON schema is valid"""
|
||||||
|
|
||||||
|
JsonValidator: jsonschema.protocols.Validator = validator_for(
|
||||||
|
UpdatesController.autoinstall_schema
|
||||||
|
)
|
||||||
|
|
||||||
|
JsonValidator.check_schema(UpdatesController.autoinstall_schema)
|
|
@ -15,7 +15,9 @@
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
import jsonschema
|
||||||
from cloudinit.config.schema import SchemaValidationError
|
from cloudinit.config.schema import SchemaValidationError
|
||||||
|
from jsonschema.validators import validator_for
|
||||||
|
|
||||||
from subiquity.server.controllers.userdata import UserdataController
|
from subiquity.server.controllers.userdata import UserdataController
|
||||||
from subiquitycore.tests.mocks import make_app
|
from subiquitycore.tests.mocks import make_app
|
||||||
|
@ -58,3 +60,12 @@ class TestUserdataController(unittest.TestCase):
|
||||||
validate.assert_called_with(
|
validate.assert_called_with(
|
||||||
data=invalid_schema, data_source="autoinstall.user-data"
|
data=invalid_schema, data_source="autoinstall.user-data"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_valid_schema(self):
|
||||||
|
"""Test that the expected autoinstall JSON schema is valid"""
|
||||||
|
|
||||||
|
JsonValidator: jsonschema.protocols.Validator = validator_for(
|
||||||
|
UserdataController.autoinstall_schema
|
||||||
|
)
|
||||||
|
|
||||||
|
JsonValidator.check_schema(UserdataController.autoinstall_schema)
|
||||||
|
|
|
@ -24,12 +24,13 @@ import jsonschema
|
||||||
import yaml
|
import yaml
|
||||||
from aiohttp import web
|
from aiohttp import web
|
||||||
from cloudinit.config.cc_set_passwords import rand_user_password
|
from cloudinit.config.cc_set_passwords import rand_user_password
|
||||||
|
from jsonschema.exceptions import ValidationError
|
||||||
from systemd import journal
|
from systemd import journal
|
||||||
|
|
||||||
from subiquity.cloudinit import get_host_combined_cloud_config
|
from subiquity.cloudinit import get_host_combined_cloud_config
|
||||||
from subiquity.common.api.server import bind, controller_for_request
|
from subiquity.common.api.server import bind, controller_for_request
|
||||||
from subiquity.common.apidef import API
|
from subiquity.common.apidef import API
|
||||||
from subiquity.common.errorreport import ErrorReporter, ErrorReportKind
|
from subiquity.common.errorreport import ErrorReport, ErrorReporter, ErrorReportKind
|
||||||
from subiquity.common.serialize import to_json
|
from subiquity.common.serialize import to_json
|
||||||
from subiquity.common.types import (
|
from subiquity.common.types import (
|
||||||
ApplicationState,
|
ApplicationState,
|
||||||
|
@ -40,6 +41,7 @@ from subiquity.common.types import (
|
||||||
PasswordKind,
|
PasswordKind,
|
||||||
)
|
)
|
||||||
from subiquity.models.subiquity import ModelNames, SubiquityModel
|
from subiquity.models.subiquity import ModelNames, SubiquityModel
|
||||||
|
from subiquity.server.autoinstall import AutoinstallError, AutoinstallValidationError
|
||||||
from subiquity.server.controller import SubiquityController
|
from subiquity.server.controller import SubiquityController
|
||||||
from subiquity.server.dryrun import DRConfig
|
from subiquity.server.dryrun import DRConfig
|
||||||
from subiquity.server.errors import ErrorController
|
from subiquity.server.errors import ErrorController
|
||||||
|
@ -222,6 +224,12 @@ class SubiquityServer(Application):
|
||||||
"minimum": 1,
|
"minimum": 1,
|
||||||
"maximum": 1,
|
"maximum": 1,
|
||||||
},
|
},
|
||||||
|
"interactive-sections": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"required": ["version"],
|
"required": ["version"],
|
||||||
"additionalProperties": True,
|
"additionalProperties": True,
|
||||||
|
@ -395,8 +403,9 @@ class SubiquityServer(Application):
|
||||||
def make_apport_report(self, kind, thing, *, wait=False, **kw):
|
def make_apport_report(self, kind, thing, *, wait=False, **kw):
|
||||||
return self.error_reporter.make_apport_report(kind, thing, wait=wait, **kw)
|
return self.error_reporter.make_apport_report(kind, thing, wait=wait, **kw)
|
||||||
|
|
||||||
async def _run_error_cmds(self, report):
|
async def _run_error_cmds(self, report: Optional[ErrorReport] = None) -> None:
|
||||||
await report._info_task
|
if report is not None and report._info_task is not None:
|
||||||
|
await report._info_task
|
||||||
Error = getattr(self.controllers, "Error", None)
|
Error = getattr(self.controllers, "Error", None)
|
||||||
if Error is not None and Error.cmds:
|
if Error is not None and Error.cmds:
|
||||||
try:
|
try:
|
||||||
|
@ -413,7 +422,7 @@ class SubiquityServer(Application):
|
||||||
return
|
return
|
||||||
report = self.error_reporter.report_for_exc(exc)
|
report = self.error_reporter.report_for_exc(exc)
|
||||||
log.error("top level error", exc_info=exc)
|
log.error("top level error", exc_info=exc)
|
||||||
if not report:
|
if not isinstance(exc, AutoinstallError) and not report:
|
||||||
report = self.make_apport_report(
|
report = self.make_apport_report(
|
||||||
ErrorReportKind.UNKNOWN, "unknown error", exc=exc
|
ErrorReportKind.UNKNOWN, "unknown error", exc=exc
|
||||||
)
|
)
|
||||||
|
@ -466,6 +475,20 @@ class SubiquityServer(Application):
|
||||||
await controller.apply_autoinstall_config()
|
await controller.apply_autoinstall_config()
|
||||||
await controller.configured()
|
await controller.configured()
|
||||||
|
|
||||||
|
def validate_autoinstall(self):
|
||||||
|
with self.context.child("core_validation", level="INFO"):
|
||||||
|
try:
|
||||||
|
jsonschema.validate(self.autoinstall_config, self.base_schema)
|
||||||
|
except ValidationError as original_exception:
|
||||||
|
# SubiquityServer currently only checks for these sections
|
||||||
|
# of autoinstall. Hardcode until we have better validation.
|
||||||
|
section = "version or interative-sessions"
|
||||||
|
new_exception: AutoinstallValidationError = AutoinstallValidationError(
|
||||||
|
section,
|
||||||
|
)
|
||||||
|
|
||||||
|
raise new_exception from original_exception
|
||||||
|
|
||||||
def load_autoinstall_config(self, *, only_early):
|
def load_autoinstall_config(self, *, only_early):
|
||||||
log.debug(
|
log.debug(
|
||||||
"load_autoinstall_config only_early %s file %s",
|
"load_autoinstall_config only_early %s file %s",
|
||||||
|
@ -480,8 +503,7 @@ class SubiquityServer(Application):
|
||||||
self.controllers.Reporting.setup_autoinstall()
|
self.controllers.Reporting.setup_autoinstall()
|
||||||
self.controllers.Reporting.start()
|
self.controllers.Reporting.start()
|
||||||
self.controllers.Error.setup_autoinstall()
|
self.controllers.Error.setup_autoinstall()
|
||||||
with self.context.child("core_validation", level="INFO"):
|
self.validate_autoinstall()
|
||||||
jsonschema.validate(self.autoinstall_config, self.base_schema)
|
|
||||||
self.controllers.Early.setup_autoinstall()
|
self.controllers.Early.setup_autoinstall()
|
||||||
else:
|
else:
|
||||||
for controller in self.controllers.instances:
|
for controller in self.controllers.instances:
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
import contextlib
|
import contextlib
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from subiquity.server.autoinstall import AutoinstallValidationError
|
||||||
from subiquity.server.controller import SubiquityController
|
from subiquity.server.controller import SubiquityController
|
||||||
from subiquitycore.tests import SubiTestCase
|
from subiquitycore.tests import SubiTestCase
|
||||||
from subiquitycore.tests.mocks import make_app
|
from subiquitycore.tests.mocks import make_app
|
||||||
|
@ -41,7 +42,6 @@ class TestController(SubiTestCase):
|
||||||
}
|
}
|
||||||
self.controller.autoinstall_key = "sample"
|
self.controller.autoinstall_key = "sample"
|
||||||
self.controller.autoinstall_key_alias = "sample-alias"
|
self.controller.autoinstall_key_alias = "sample-alias"
|
||||||
self.controller.autoinstall_default = "default-data"
|
|
||||||
self.controller.setup_autoinstall()
|
self.controller.setup_autoinstall()
|
||||||
mock_load.assert_called_once_with("some-sample-data")
|
mock_load.assert_called_once_with("some-sample-data")
|
||||||
|
|
||||||
|
@ -56,5 +56,36 @@ class TestController(SubiTestCase):
|
||||||
mock_load.reset_mock()
|
mock_load.reset_mock()
|
||||||
self.controller.autoinstall_key = "inexistent"
|
self.controller.autoinstall_key = "inexistent"
|
||||||
self.controller.autoinstall_key_alias = "inexistent"
|
self.controller.autoinstall_key_alias = "inexistent"
|
||||||
|
self.controller.autoinstall_default = "default-data"
|
||||||
self.controller.setup_autoinstall()
|
self.controller.setup_autoinstall()
|
||||||
mock_load.assert_called_once_with("default-data")
|
mock_load.assert_called_once_with("default-data")
|
||||||
|
|
||||||
|
def test_autoinstall_validation(self):
|
||||||
|
"""Test validation error type and no apport reporting"""
|
||||||
|
|
||||||
|
self.controller.autoinstall_schema = {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"some-key": {
|
||||||
|
"type": "boolean",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
self.bad_ai_data = {"some-key": "not a bool"}
|
||||||
|
|
||||||
|
self.controller.autoinstall_key = "some-key"
|
||||||
|
|
||||||
|
# Assert error type is correct
|
||||||
|
with self.assertRaises(AutoinstallValidationError) as ctx:
|
||||||
|
self.controller.validate_autoinstall(self.bad_ai_data)
|
||||||
|
|
||||||
|
exception = ctx.exception
|
||||||
|
|
||||||
|
# Assert error section is based on autoinstall_key
|
||||||
|
self.assertEquals(exception.owner, "some-key")
|
||||||
|
|
||||||
|
# Assert apport report is not created
|
||||||
|
# This only checks that controllers do not manually create an apport
|
||||||
|
# report on validation. Should also be tested in Server
|
||||||
|
self.controller.app.make_apport_report.assert_not_called()
|
||||||
|
|
|
@ -17,7 +17,11 @@ import os
|
||||||
import shlex
|
import shlex
|
||||||
from unittest.mock import Mock, patch
|
from unittest.mock import Mock, patch
|
||||||
|
|
||||||
|
import jsonschema
|
||||||
|
from jsonschema.validators import validator_for
|
||||||
|
|
||||||
from subiquity.common.types import PasswordKind
|
from subiquity.common.types import PasswordKind
|
||||||
|
from subiquity.server.autoinstall import AutoinstallValidationError
|
||||||
from subiquity.server.server import (
|
from subiquity.server.server import (
|
||||||
MetaController,
|
MetaController,
|
||||||
SubiquityServer,
|
SubiquityServer,
|
||||||
|
@ -141,6 +145,56 @@ early-commands: ["{cmd}"]
|
||||||
self.assertEqual(after_early, self.server.autoinstall_config)
|
self.assertEqual(after_early, self.server.autoinstall_config)
|
||||||
|
|
||||||
|
|
||||||
|
class TestAutoinstallValidation(SubiTestCase):
|
||||||
|
async def asyncSetUp(self):
|
||||||
|
opts = Mock()
|
||||||
|
opts.dry_run = True
|
||||||
|
opts.output_base = self.tmp_dir()
|
||||||
|
opts.machine_config = "examples/machines/simple.json"
|
||||||
|
self.server = SubiquityServer(opts, None)
|
||||||
|
self.server.base_schema = {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"some-key": {
|
||||||
|
"type": "boolean",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
self.server.make_apport_report = Mock()
|
||||||
|
|
||||||
|
def test_valid_schema(self):
|
||||||
|
"""Test that the expected autoinstall JSON schema is valid"""
|
||||||
|
|
||||||
|
JsonValidator: jsonschema.protocols.Validator = validator_for(
|
||||||
|
SubiquityServer.base_schema
|
||||||
|
)
|
||||||
|
|
||||||
|
JsonValidator.check_schema(SubiquityServer.base_schema)
|
||||||
|
|
||||||
|
def test_autoinstall_validation__error_type(self):
|
||||||
|
"""Test that bad autoinstall data throws AutoinstallValidationError"""
|
||||||
|
|
||||||
|
bad_ai_data = {"some-key": "not a bool"}
|
||||||
|
self.server.autoinstall_config = bad_ai_data
|
||||||
|
|
||||||
|
with self.assertRaises(AutoinstallValidationError):
|
||||||
|
self.server.validate_autoinstall()
|
||||||
|
|
||||||
|
async def test_autoinstall_validation__no_error_report(self):
|
||||||
|
"""Test no apport reporting"""
|
||||||
|
|
||||||
|
exception = AutoinstallValidationError("Mock")
|
||||||
|
|
||||||
|
loop = Mock()
|
||||||
|
context = {"exception": exception}
|
||||||
|
|
||||||
|
with patch("subiquity.server.server.log"):
|
||||||
|
with patch.object(self.server, "_run_error_cmds"):
|
||||||
|
self.server._exception_handler(loop, context)
|
||||||
|
|
||||||
|
self.server.make_apport_report.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
class TestMetaController(SubiTestCase):
|
class TestMetaController(SubiTestCase):
|
||||||
async def test_interactive_sections_not_present(self):
|
async def test_interactive_sections_not_present(self):
|
||||||
mc = MetaController(make_app())
|
mc = MetaController(make_app())
|
||||||
|
|
|
@ -50,5 +50,6 @@ def make_app(model=None):
|
||||||
app.log_syslog_id = None
|
app.log_syslog_id = None
|
||||||
app.report_start_event = mock.Mock()
|
app.report_start_event = mock.Mock()
|
||||||
app.report_finish_event = mock.Mock()
|
app.report_finish_event = mock.Mock()
|
||||||
|
app.make_apport_report = mock.Mock()
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|
Loading…
Reference in New Issue