diff --git a/docs/releases.rst b/docs/releases.rst index 3c691f316f..5f660eb8ca 100644 --- a/docs/releases.rst +++ b/docs/releases.rst @@ -50,6 +50,11 @@ Leonova. __ https://github.com/teemtee/docs/tree/main/logo +The :ref:`/plugins/provision/beaker` provision plugin gains +support for submitting jobs on behalf of a group through +``job-group`` key. The submitting user must be a member of +the given job group. + tmt-1.39.0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tmt/schemas/provision/beaker.yaml b/tmt/schemas/provision/beaker.yaml index 01953b01fc..0f56879f64 100644 --- a/tmt/schemas/provision/beaker.yaml +++ b/tmt/schemas/provision/beaker.yaml @@ -54,5 +54,8 @@ properties: items: type: string + job-group: + type: string + required: - how diff --git a/tmt/steps/provision/mrack.py b/tmt/steps/provision/mrack.py index bf072f108b..a73aeca82d 100644 --- a/tmt/steps/provision/mrack.py +++ b/tmt/steps/provision/mrack.py @@ -923,6 +923,14 @@ class BeakerGuestData(tmt.steps.provision.GuestSshData): multiple=True, normalize=tmt.utils.normalize_string_list) + job_group: Optional[str] = field( + default=None, + option='--job-group', + metavar='GROUPNAME', + help=""" + If set, Beaker jobs will be submitted on behalf of ``GROUPNAME``. + """) + @dataclasses.dataclass class ProvisionBeakerData(BeakerGuestData, tmt.steps.provision.ProvisionStepData): @@ -959,7 +967,7 @@ class CreateJobParameters: whiteboard: Optional[str] beaker_job_owner: Optional[str] public_key: list[str] - group: str = 'linux' + group: Optional[str] def to_mrack(self) -> dict[str, Any]: data = dataclasses.asdict(self) @@ -1083,6 +1091,7 @@ class GuestBeaker(tmt.steps.provision.GuestSsh): kickstart: dict[str, str] beaker_job_owner: Optional[str] = None + job_group: Optional[str] = None # Provided in Beaker response job_id: Optional[str] @@ -1160,7 +1169,8 @@ def _create(self, tmt_name: str) -> None: name=f'{self.image}-{self.arch}', whiteboard=self.whiteboard or tmt_name, beaker_job_owner=self.beaker_job_owner, - public_key=self.public_key) + public_key=self.public_key, + group=self.job_group) try: response = self.api.create(data) @@ -1181,6 +1191,16 @@ def _create(self, tmt_name: str) -> None: f"Failed to create Beaker job, job owner '{self.beaker_job_owner}' " "is not a valid submission delegate.") from exc + if 'is not a valid group' in cause.faultString: + raise ProvisionError( + f"Failed to create Beaker job, job group '{self.job_group}' " + "was refused as unknown.") from exc + + if 'is not a member of group' in cause.faultString: + raise ProvisionError( + "Failed to create Beaker job, submitting user is not " + "a member of group '{self.job_group}'") from exc + raise ProvisionError('Failed to create Beaker job') from exc if response: