identity: move config validation to load_autoinstall_data
Moves the logic for checking if user-data or identity section is provided (on server) in the autoinstall config to the load_autoinstall_data function. Without this change, the exception thrown in apply_autoinstall_config won't halt the installer until the postinstall steps (LP: 2060547).
This commit is contained in:
parent
c6a1b583de
commit
88f8b21633
|
@ -22,8 +22,8 @@ import attr
|
||||||
from subiquity.common.apidef import API
|
from subiquity.common.apidef import API
|
||||||
from subiquity.common.resources import resource_path
|
from subiquity.common.resources import resource_path
|
||||||
from subiquity.common.types import IdentityData, UsernameValidation
|
from subiquity.common.types import IdentityData, UsernameValidation
|
||||||
|
from subiquity.server.autoinstall import AutoinstallError
|
||||||
from subiquity.server.controller import SubiquityController
|
from subiquity.server.controller import SubiquityController
|
||||||
from subiquitycore.context import with_context
|
|
||||||
|
|
||||||
log = logging.getLogger("subiquity.server.controllers.identity")
|
log = logging.getLogger("subiquity.server.controllers.identity")
|
||||||
|
|
||||||
|
@ -79,18 +79,29 @@ class IdentityController(SubiquityController):
|
||||||
crypted_password=data["password"],
|
crypted_password=data["password"],
|
||||||
)
|
)
|
||||||
self.model.add_user(identity_data)
|
self.model.add_user(identity_data)
|
||||||
|
|
||||||
@with_context()
|
|
||||||
async def apply_autoinstall_config(self, context=None):
|
|
||||||
if self.model.user:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# The identity section is required except if (any):
|
||||||
|
# 1. a user-data section is provided
|
||||||
if "user-data" in self.app.autoinstall_config:
|
if "user-data" in self.app.autoinstall_config:
|
||||||
return
|
return
|
||||||
if self.app.base_model.target is None:
|
# 2. we are installing not-Server (Desktop)
|
||||||
return
|
|
||||||
if self.app.base_model.source.current.variant != "server":
|
if self.app.base_model.source.current.variant != "server":
|
||||||
return
|
return
|
||||||
raise Exception("neither identity nor user-data provided")
|
# 3. we are only refreshing the reset partition
|
||||||
|
# (The identity controller doesn't figure this out until the apply
|
||||||
|
# step, so we are going to cheat and inspect the situation here)
|
||||||
|
storage_config = self.app.autoinstall_config.get("storage")
|
||||||
|
if (
|
||||||
|
storage_config is not None
|
||||||
|
and storage_config.get("layout") is not None
|
||||||
|
and storage_config["layout"].get("reset-partition-only")
|
||||||
|
):
|
||||||
|
return
|
||||||
|
# 4. identity section is interactive
|
||||||
|
if self.interactive():
|
||||||
|
return
|
||||||
|
raise AutoinstallError("neither identity nor user-data provided")
|
||||||
|
|
||||||
def make_autoinstall(self):
|
def make_autoinstall(self):
|
||||||
if self.model.user is None:
|
if self.model.user is None:
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
import jsonschema
|
import jsonschema
|
||||||
from jsonschema.validators import validator_for
|
from jsonschema.validators import validator_for
|
||||||
|
|
||||||
|
from subiquity.server.autoinstall import AutoinstallError
|
||||||
from subiquity.server.controllers.identity import IdentityController
|
from subiquity.server.controllers.identity import IdentityController
|
||||||
from subiquitycore.tests import SubiTestCase
|
from subiquitycore.tests import SubiTestCase
|
||||||
from subiquitycore.tests.mocks import make_app
|
from subiquitycore.tests.mocks import make_app
|
||||||
|
@ -42,10 +43,48 @@ class TestControllerUserCreationFlows(SubiTestCase):
|
||||||
|
|
||||||
async def test_server_requires_identity_case_4a1(self):
|
async def test_server_requires_identity_case_4a1(self):
|
||||||
self.app.base_model.source.current.variant = "server"
|
self.app.base_model.source.current.variant = "server"
|
||||||
with self.assertRaises(Exception):
|
|
||||||
await self.ic.apply_autoinstall_config()
|
# Autoinstall: no identity or user data and identity is not interactive
|
||||||
|
self.app.autoinstall_config = {"interactive-sections": ["not-identity"]}
|
||||||
|
with self.assertRaises(AutoinstallError):
|
||||||
|
self.ic.load_autoinstall_data(None)
|
||||||
|
|
||||||
|
async def test_server_requires_identity_case_4a1__ok_interactive(self):
|
||||||
|
"""Test no require identity for interactive identity"""
|
||||||
|
self.app.base_model.source.current.variant = "server"
|
||||||
|
|
||||||
|
# Explicitly interactive
|
||||||
|
self.app.autoinstall_config = {"interactive-sections": ["identity"]}
|
||||||
|
self.ic.load_autoinstall_data(None)
|
||||||
|
|
||||||
|
# Implicitly interactive
|
||||||
|
self.app.autoinstall_config = {"interactive-sections": ["*"]}
|
||||||
|
self.ic.load_autoinstall_data(None)
|
||||||
|
|
||||||
|
# No Autoinstall => interactive
|
||||||
|
self.app.autoinstall_config = {}
|
||||||
|
self.ic.load_autoinstall_data(None)
|
||||||
|
|
||||||
|
async def test_server_requires_identity_case_4a1__reset_only_true(self):
|
||||||
|
"""Test no require identity for reset-partition-only=yes."""
|
||||||
|
self.app.base_model.source.current.variant = "server"
|
||||||
|
|
||||||
|
# No raise if reset-parition-only specified
|
||||||
|
self.app.autoinstall_config = {
|
||||||
|
"storage": {"layout": {"reset-partition-only": True}}
|
||||||
|
}
|
||||||
|
self.ic.load_autoinstall_data(None)
|
||||||
|
|
||||||
|
async def test_server_requires_identity_case_4a1__reset_only_false(self):
|
||||||
|
"""Test require identity for reset-partition-only=no."""
|
||||||
|
self.app.base_model.source.current.variant = "server"
|
||||||
|
|
||||||
|
# raises if no reset-parition-only in storage:layout:
|
||||||
|
self.app.autoinstall_config = {"storage": {"layout": {}}}
|
||||||
|
with self.assertRaises(AutoinstallError):
|
||||||
|
self.ic.load_autoinstall_data(None)
|
||||||
|
|
||||||
async def test_desktop_does_not_require_identity_case_4a2(self):
|
async def test_desktop_does_not_require_identity_case_4a2(self):
|
||||||
self.app.base_model.source.current.variant = "desktop"
|
self.app.base_model.source.current.variant = "desktop"
|
||||||
await self.ic.apply_autoinstall_config()
|
self.ic.load_autoinstall_data(None)
|
||||||
# should not raise
|
# should not raise
|
||||||
|
|
Loading…
Reference in New Issue