feat(_task): allow secret overrides on reusable tasks#1108
Open
EngHabu wants to merge 2 commits into
Open
Conversation
`flyteidl2.imagebuilder.PythonWheels` only declares `dir` / `options` / `secret_mounts` — there's no `package_name` field today. The SDK's remote-builder serializer at remote_builder.py:262 sets `PythonWheels(... package_name=layer.package_name, ...)`, which the proto-generated message rejects with: Protocol message PythonWheels has no "package_name" field. Consequence: any image with a `PythonWheels` layer (`Image.with_local_v2()`, `Image.with_local_v2_plugins(...)`, or any caller that adds the layer directly) blows up at image-build time on the remote builder. The local docker builder is unaffected because it reads `package_name` straight off the Python dataclass. This was a known gap — the wheel-changes commit (1cdbd6b) literally says "Will need to update the remote builder as well." Until the proto + the server-side builder gain a real `package_name` field, we can sidestep the proto entirely by emitting the equivalent local docker-builder behavior using existing wire-compatible messages: CopyConfig{src=<staged wheel dir>, dst=/<dir_name>} Commands{cmd=[ "pip install ... --find-links /<dir_name> --no-deps --no-index --force-reinstall <package_name>", "pip install ... <package_name>", ]} The two pip invocations mirror exactly what `docker_builder.PythonWheelHandler` runs locally: 1. Install the wheel WITHOUT deps from --find-links (--no-index guarantees we never reach PyPI for the package itself). 2. Install dependencies normally (pip resolves the dep tree from PyPI for everything except the package we just baked). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
``task.override(secrets=...)`` previously raised when the task's env was reusable. The intent was to keep one pool per env, but the actor pool key (``extract_unique_id_and_image``) already includes the task's ``security_context`` — so a secret override deterministically maps to a *different* actor pool, not a polluted one. Concrete use case unblocked: per-user / per-identifier credentials secrets on a reusable claude-session env. Each identifier gets its own actor pod hosting that user's concurrent sessions; cross-identifier isolation is preserved by the pool-key hash. Resources and env_vars remain locked: they would change the pod spec (CPU/memory limits, env values seen at exec time) without changing the pool key, so the same actor pool could end up running tasks that disagree on those values. Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
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.
Motivation
task.override(secrets=...)currently raises when the task's environment is reusable:The guard's intent — keep one actor pool per env — is already enforced downstream.
extract_unique_id_and_image(in_internal/runtime/reuse.py) hashes the task'ssecurity_contextinto the actor pool key. A secret override deterministically maps to a different actor pool, not a polluted shared one.Concrete use case
We're building a multi-user "Claude Code in Flyte" service where each user owns a per-identifier credentials secret (
<identifier>-claude-session). The launcher does:We want
claude_sessionto be reusable so multiple concurrent sessions for the same user share an actor pod (and the same FUSE-mounted volume at /root). Cross-user isolation comes from the secret override → different actor pool. The current guard blocks this entirely;reusable='off'would cost us the pool sharing we explicitly want.What changed
Drop the
secretscheck from thereusableguard inTask.override(). Resources and env_vars stay locked — they would mutate the pod spec without changing the actor pool key (so a single pool could end up running tasks that disagree on CPU/memory limits or environment values).Test plan
task.override(secrets=...)on a reusable env now schedules into a per-secret actor pool (rather than raising at override-time).🤖 Generated with Claude Code