Surface T-shirt size elements in the backoffice admin - #2467
Draft
Elena Peña Tapia (ElePT) wants to merge 2 commits into
Draft
Surface T-shirt size elements in the backoffice admin#2467Elena Peña Tapia (ElePT) wants to merge 2 commits into
Elena Peña Tapia (ElePT) wants to merge 2 commits into
Conversation
Register a function's size catalog (its sizes map) and default size where operators actually work: - FunctionSizeInline on ProgramAdmin: edit each size -> compute profile inline on the function page, mirroring the upload endpoint's sizes payload. - default_size field in a new Sizes fieldset, with its dropdown limited to the function's own sizes (Program.clean() rejects a default belonging to another function). - sizes_summary column on the Program changelist (count + default). - sizes_using column on ComputeProfile so operators see a profile is referenced before editing/deleting it (the FK is PROTECT). Both changelist columns are annotated to avoid per-row queries.
A Program created purely in the Django admin previously got only model defaults, skipping two runnable-critical steps the upload use case performs: - CE project assignment. ProgramAdminForm.clean() now assigns a Code Engine project to a Fleets function (provider's active project, or the deployment default) via CodeEngineProject.objects.assign_to_program, and BLOCKS the save with the upload endpoint's own message when none is available — a Fleets function with no active project cannot run. - Default-size seeding. ProgramAdmin.save_related() seeds the deployment default size (DEFAULT_FUNCTION_SIZE -> DEFAULT_FUNCTION_SIZE_PROFILE) for a size-less Fleets function, like upload does. Runs after the inline FunctionSize formset so an operator's declared sizes are respected; skipped when a default is already set. Non-fatal + warns when the profile is unregistered. Reuses upload.py logic via a new module-level seed_default_size() (the use case method now delegates) and a promoted no_ce_project_message(), keeping one source of truth. Admin-only; no model or migration changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The T-shirt size models (
ComputeProfile,FunctionSize,Program.default_size) shipped in 0.36.0, but a function's size catalog (its sizes map) and its default size weren't surfaced in the backoffice admin where operators work. This PR adds them, and — as a second step — makes a Fleets function created purely in the admin actually runnable.Part 1 — Surface the size elements
On the Program (Function) page
FunctionSizeInline— a function's whole sizes map (each size key → compute profile) is now editable inline on its own page, mirroring the catalog the upload endpoint'ssizespayload builds.default_sizefield in a new "Sizes" fieldset. Its dropdown is restricted to the function's own sizes (Program.clean()rejects a default belonging to another function).sizes_summarychangelist column —N (default: s)or-.On the ComputeProfile page
sizes_usingcolumn — reference count, so an operator sees a profile is in use before editing/deleting it (the FK isPROTECT).Both changelist columns are annotated to avoid per-row queries.
Part 2 — Make a backoffice-created Fleets function runnable
A
Programcreated purely in the admin previously got only model defaults, skipping two runnable-critical steps the upload use case performs. Replicated here, reusingupload.pylogic (single source of truth):ProgramAdminForm.clean()assigns a Code Engine project to a Fleets function (provider's active project, or the deployment default) viaCodeEngineProject.objects.assign_to_program, and blocks the save — with the upload endpoint's own message — when none is available. A Fleets function with no active CE project cannot run, so this fails loud rather than persisting a dead function.ProgramAdmin.save_related()seeds the deployment default size (DEFAULT_FUNCTION_SIZE→DEFAULT_FUNCTION_SIZE_PROFILE) for a size-less Fleets function. Runs after the inlineFunctionSizeformset, so an operator's declared sizes are respected; skipped when a default is already set. Non-fatal + warns when the profile is unregistered.Refactor: extracted a module-level
seed_default_size()(the use-case method now delegates) and promoted_no_ce_project_message→no_ce_project_message.Scope
Job.compute_profile(the deprecated string) — that's a separate branch's concern.Behavioral note (blocking tradeoff)
Because
clean()blocks any Fleets save that can't get an active CE project, a legacy/misconfigured Fleets function whose provider has no active project (and no default configured) cannot be saved — even to disable it — until a project is assignable. This is the intended "fail-loud" behavior (mirrors the upload endpoint); the operator assigns a project in the same edit.Testing
gateway/tests/test_tshirt_admin.py(21 tests): inline rendering,default_sizedropdown scoping,sizes_usingcount; CE auto-assign (provider + default paths), blocking when unconfigured / no project / inactive project, operator-chosen project preserved, Ray no-ops; default-size seeding (present/absent profile, no-clobber, sizes-declared), plus two end-to-end adminclienttests proving the real add form blocks a non-runnable function and creates a runnable one.manage.py checkclean;pylint10.00/10 on both source files;blackclean.test_http_server/test_function_access_clientfail in this env without Redis/a running server — untouched by this PR.)