Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NAS-133206 / 25.10 / Convert boot.* to versioned API #15524

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/middlewared/middlewared/api/v25_04_0/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from .app_ix_volume import * # noqa
from .app_registry import * # noqa
from .auth import * # noqa
from .boot import * # noqa
from .boot_environments import * # noqa
from .catalog import * # noqa
from .cloud_backup import * # noqa
Expand Down
94 changes: 94 additions & 0 deletions src/middlewared/middlewared/api/v25_04_0/boot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
from typing import Literal

from pydantic import Field, PositiveInt

from middlewared.api.base import BaseModel, NotRequired


__all__ = [
"BootGetDisksArgs", "BootGetDisksResult", "BootAttachArgs", "BootAttachResult", "BootDetachArgs",
"BootDetachResult", "BootReplaceArgs", "BootReplaceResult", "BootScrubArgs", "BootScrubResult",
"BootSetScrubIntervalArgs", "BootSetScrubIntervalResult", "BootUpdateInitramfsArgs", "BootUpdateInitramfsResult",
"BootFormatArgs", "BootFormatResult"
]


class BootAttachOptions(BaseModel):
expand: bool = False


class BootFormatOptions(BaseModel):
size: int = NotRequired
legacy_schema: Literal["BIOS_ONLY", "EFI_ONLY", None] = None


class BootUpdateInitramfsOptions(BaseModel):
database: str | None = None
force: bool = False


class BootGetDisksArgs(BaseModel):
pass


class BootGetDisksResult(BaseModel):
result: list[str]


class BootAttachArgs(BaseModel):
dev: str
options: BootAttachOptions = Field(default_factory=BootAttachOptions)


class BootAttachResult(BaseModel):
result: None


class BootDetachArgs(BaseModel):
dev: str


class BootDetachResult(BaseModel):
result: None


class BootFormatArgs(BaseModel):
dev: str
options: BootFormatOptions = Field(default_factory=BootFormatOptions)


class BootFormatResult(BaseModel):
result: None


class BootReplaceArgs(BaseModel):
label: str
dev: str


class BootReplaceResult(BaseModel):
result: None


class BootScrubArgs(BaseModel):
pass


class BootScrubResult(BaseModel):
result: None


class BootSetScrubIntervalArgs(BaseModel):
interval: PositiveInt


class BootSetScrubIntervalResult(BaseModel):
result: PositiveInt


class BootUpdateInitramfsArgs(BaseModel):
options: BootUpdateInitramfsOptions = Field(default_factory=BootUpdateInitramfsOptions)


class BootUpdateInitramfsResult(BaseModel):
result: bool
44 changes: 15 additions & 29 deletions src/middlewared/middlewared/plugins/boot.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import asyncio
import os

from contextlib import asynccontextmanager
from middlewared.schema import accepts, Bool, Dict, Int, List, Str, returns, Patch
from middlewared.api import api_method
from middlewared.api.current import (
BootGetDisksArgs, BootGetDisksResult, BootAttachArgs, BootAttachResult, BootDetachArgs,
BootDetachResult, BootReplaceArgs, BootReplaceResult, BootScrubArgs, BootScrubResult,
BootSetScrubIntervalArgs, BootSetScrubIntervalResult, BootUpdateInitramfsArgs, BootUpdateInitramfsResult
)
from middlewared.schema import accepts, returns, Patch
from middlewared.service import CallError, Service, job, private
from middlewared.utils import run
from middlewared.utils.disks import valid_zfs_partition_uuids
from middlewared.validators import Range


BOOT_ATTACH_REPLACE_LOCK = 'boot_attach_replace'
BOOT_POOL_NAME = BOOT_POOL_DISKS = None
Expand Down Expand Up @@ -62,8 +67,7 @@ async def clear_disks_cache(self):
global BOOT_POOL_DISKS
BOOT_POOL_DISKS = None

@accepts(roles=['READONLY_ADMIN'])
@returns(List('disks', items=[Str('disk')]))
@api_method(BootGetDisksArgs, BootGetDisksResult, roles=['DISK_READ'])
async def get_disks(self):
"""
Returns disks of the boot pool.
Expand All @@ -81,14 +85,7 @@ async def get_boot_type(self):
# https://wiki.debian.org/UEFI
return 'EFI' if os.path.exists('/sys/firmware/efi') else 'BIOS'

@accepts(
Str('dev'),
Dict(
'options',
Bool('expand', default=False),
),
)
@returns()
@api_method(BootAttachArgs, BootAttachResult, roles=['DISK_WRITE'])
@job(lock=BOOT_ATTACH_REPLACE_LOCK)
async def attach(self, job, dev, options):
"""
Expand Down Expand Up @@ -138,8 +135,7 @@ async def attach(self, job, dev, options):
await self.middleware.call('zfs.pool.online', BOOT_POOL_NAME, zfs_dev_part['name'], True)
await self.update_initramfs()

@accepts(Str('dev'))
@returns()
@api_method(BootDetachArgs, BootDetachResult, roles=['DISK_WRITE'])
async def detach(self, dev):
"""
Detach given `dev` from boot pool.
Expand All @@ -148,8 +144,7 @@ async def detach(self, dev):
await self.middleware.call('zfs.pool.detach', BOOT_POOL_NAME, dev, {'clear_label': True})
await self.update_initramfs()

@accepts(Str('label'), Str('dev'))
@returns()
@api_method(BootReplaceArgs, BootReplaceResult, roles=['DISK_WRITE'])
@job(lock=BOOT_ATTACH_REPLACE_LOCK)
async def replace(self, job, label, dev):
"""
Expand Down Expand Up @@ -187,8 +182,7 @@ async def replace(self, job, label, dev):
await self.middleware.call('boot.install_loader', dev)
await self.update_initramfs()

@accepts()
@returns()
@api_method(BootScrubArgs, BootScrubResult, roles=['BOOT_ENV_WRITE'])
@job(lock='boot_scrub')
async def scrub(self, job):
"""
Expand All @@ -197,10 +191,7 @@ async def scrub(self, job):
subjob = await self.middleware.call('pool.scrub.scrub', BOOT_POOL_NAME)
return await job.wrap(subjob)

@accepts(
Int('interval', validators=[Range(min_=1)])
)
@returns(Int('interval'))
@api_method(BootSetScrubIntervalArgs, BootSetScrubIntervalResult, roles=['BOOT_ENV_WRITE'])
async def set_scrub_interval(self, interval):
"""
Set Automatic Scrub Interval value in days.
Expand All @@ -213,12 +204,7 @@ async def set_scrub_interval(self, interval):
)
return interval

@accepts(Dict(
'options',
Str('database', default=None, null=True),
Bool('force', default=False),
))
@private
@api_method(BootUpdateInitramfsArgs, BootUpdateInitramfsResult, private=True)
async def update_initramfs(self, options):
"""
Returns true if initramfs was updated and false otherwise.
Expand Down
15 changes: 4 additions & 11 deletions src/middlewared/middlewared/plugins/boot_/format.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
from middlewared.schema import accepts, Dict, Int, Str
from middlewared.service import CallError, private, Service
from middlewared.api import api_method
from middlewared.api.current import BootFormatArgs, BootFormatResult
from middlewared.service import CallError, Service
from middlewared.utils import run


class BootService(Service):

@accepts(
Str('dev'),
Dict(
'options',
Int('size'),
Str('legacy_schema', enum=[None, 'BIOS_ONLY', 'EFI_ONLY'], null=True, default=None),
)
)
@private
@api_method(BootFormatArgs, BootFormatResult, private=True)
async def format(self, dev, options):
"""
Format a given disk `dev` using the appropriate partition layout
Expand Down