Skip to content

feat(backend): add MLMD-to-native data migration and startup gate #14029

Open

Description

@jeffspahr

Current migration contract — October 22, 2026

Metadata migration, execution continuity, and access to artifact bytes are separate requirements. This issue owns the historical-data and execution transition to native storage. #14031 owns the authenticated backend artifact-content contract. Migrating an Artifact record or preserving its URI does not grant access to the object.

Actual 2.18 starting point

The selected 2.18 release plan restores 2.17 artifact ownership compatibility through #15044, followed by the upgrade and agent assessment guides in #14703. Both PRs remain open; the release branch still enforces the stronger ownership policy until the rollback merges.

Under that plan, 2.18 retains MLMD and its existing artifact-serving paths. It does not ship the new auto|storage|key-prefix authorization framework, external adoption policies, authorization readiness records, or versioned receiver protocol from the deferred #14884. The unreleased KFP_SECURITY_ARTIFACT_OWNERSHIP_MODE audit/enforce setting is removed; there is no artifact audit exception for operators to enable as a migration prerequisite. Existing lookup-policy controls keep their prior scope.

A 3.0 upgrade must therefore support first adoption of its chosen artifact authorization system from an actual 2.18 installation. It cannot require an intermediate 2.18 approval rollout, historical-object move, metadata registration, or storage cutover. The preserved reference #14883 and backport tests are design and regression assets, not a merge target or evidence that those resources already exist in an upgrading cluster. #14031 owns the backend-first replacement without requiring the reference mode/readiness/adoption framework. Draft #15045 prepares removal of the mandatory-prefix and central-HTTP restrictions; it requires trusted backend object authorization before merge, since native metadata and broad credentials alone do not establish isolation. Master has no runtime MLMD dependency; the migration tool may read MLMD to import history, but the new artifact-serving boundary must not depend on it.

Retained 2.18 ownership behavior can leave cross-tenant exposure with shared/broad credentials or incomplete/caller-associated metadata. This is not the final 3.0 security contract. Preserve independent authentication/SAR, destination, credential, path, volume and response protections, and prove the new boundary does not inherit that exposure as a fallback.

Database paths and delivered work

  • #14782 is merged into release-2.18; the exporter prerequisite is delivered.
  • #14729 remains a proposed replacement-installation import of definitions and completed history. It preserves artifact URIs without copying objects, leaves imported schedules disabled, and does not migrate active workloads or make imported history executable/cache-eligible. Successful import does not establish artifact-read compatibility or an in-place upgrade.
  • #14769 supplies a separate scheduling prerequisite; it is not artifact adoption, MLMD history migration, or proof of in-place execution continuity.
  • 2.18 schema reconciliation and reference backfills run synchronously during API startup and can delay readiness or block writes. Background schedule adoption is separate. The delivered JobUUID lookup-index helper preserves existing column types and uses explicit online/concurrent creation; it does not narrow varchar(255) to 191. These improvements do not make all startup work nonblocking.
  • Ordinary manual SQL for retention indexes is removed in 2.18 by merged #14877. The elected GC prepares the two indexes sequentially in the background when retention or prepare-only is enabled. RUNS_GC_INDEX_BUILD_TIMEOUT bounds each build (default 12h); metadata-lock waits are bounded separately. RUNS_GC_INDEX_PREPARE_ONLY=true, applied consistently across replicas, prepares indexes without archive/delete. Keep retention windows disabled while staging, finish the rollout, then separately enable catch-up. Previously configured retention paused by missing indexes can otherwise resume automatically after preparation and the GC interval. Matching interrupted PostgreSQL builds recover automatically; conflicting definitions still require diagnosis. Online builds consume IO/space and may briefly delay writes at metadata locks. Retention disabled with prepare-only off does no preparation. This recovery does not apply to the separate JobUUID startup-index path. The master counterpart #14876 remains open.

None of those 2.18 database operations migrates MLMD history into native storage. The release-2.18 retention preparation guide and #14703 detail the operator controls and remaining impact.

Artifact-access completion requirements

Current master still imposes a namespace-prefix boundary even when native metadata matches; the existing validator therefore does not make arbitrary historical roots readable merely because their records were imported. This describes the current implementation, not a requirement to retain that restriction in the replacement design.

  • Deliver the backend-owned storage authority in #14031, preserving already-authorized historical/custom roots using trusted storage configuration and actual namespace grants. Do not mandate object moves or new native Artifact IDs solely to keep an authorized content path. Define an explicit migration or actionable block where actual authority cannot be established; do not treat a URI, importer-created provenance, or a native metadata row as an object-access grant.
  • Validate authenticated previews/downloads independently of metadata-import counts. Cover namespace-prefixed and custom roots, registered and unregistered historical objects, known foreign ownership, forged/imported claims, shared or overly broad grants, unavailable authority and revoked credentials.
  • Start the populated 2.18-to-3.0 fixture without the deferred approval/readiness/receiver resources. Test supported first adoption, mixed versions, interruption/recovery and rollback; old permissive ownership behavior must not silently reappear after the new boundary activates.
  • Keep metadata migration, active-execution transition, cache eligibility and object access separately evidenced. Artifact content must not require runtime MLMD or universal historical metadata import; history views and execution continuity still need their own supported migration contract.

The original in-place migration/startup-gate and execution-continuity requirements remain open unless explicitly replaced by an approved supported alternative. #14421 tracks 2.18 acceptance; #14031 tracks the 3.0 artifact boundary. Runtime policy changes remain separate implementation and review work.

Current scope — October 11, 2026

Reconciled against master ac2603694 and linked PR merge states. This section supersedes conflicting current-state claims in the retained description and earlier discussion.

Delivered work and its boundary

Remaining scope and completion gate

  • Deliver the supported MLMD-to-native migration path with trusted ownership, task forms/hierarchy, artifacts/metrics/relationships, idempotence/resume, validation and a durable completion marker as specified below.
  • Establish the startup/preflight gate for fresh, unmigrated, partial/failed and validated installations. Current startup schema migration is not evidence of historical-data migration completion.
  • Resolve the execution-transition contract: running/pending/suspended old workflows, old clients/images/packages, controller/API overlap, historical retries and eligible cache reuse or explicit supported alternatives. Preserve the October 6 acceptance below.
  • Publish backup, progress, recovery and rollback guidance; qualify the chosen contract with actual old-to-new, multi-namespace upgrade tests.

Keep this issue as the upgrade blocker unless the project explicitly declares in-place upgrades unsupported and documents a supported alternative. A replacement-history import alone does not satisfy execution continuity. Before closing, both historical migration and execution transition need evidence, or the remaining transition scope needs a separately owned release-blocking issue. The detailed migration/security/acceptance requirements below remain applicable subject to the October 22 contract above. Their historical implementation description is not a requirement to preserve frontend-owned policy, mandatory prefixes, or an Artifact API dependency for every content request.

Retained detailed specification and original context

Chore description

Kubeflow Pipelines needs a supported upgrade path that migrates historical runtime
metadata from ML Metadata (MLMD) into the native KFP task, artifact, metric, and
relationship storage introduced by the MLMD-removal work.

The release also needs an API-server startup gate that detects an existing
MLMD-backed installation whose migration has not completed. In that state, the
server should refuse to start with an actionable error instead of becoming healthy
while historical runs, tasks, artifacts, metrics, relationships, and cache records
are silently unavailable through the new APIs.

This can be implemented separately from #13986, but it is a release blocker for
upgrades from MLMD-backed KFP versions unless the project explicitly declares those
upgrades unsupported and documents an alternative path.

Background

#11760 tracks removing MLMD as a KFP dependency. PR #13986 replaces MLMD-backed
runtime reads and writes with native run-scoped task and artifact APIs and removes
the MLMD deployment components.

The MLMD-removal design's Migration section
already defines the upgrade contract:

  • provide a migration tool that converts MLMD executions into native tasks;
  • recreate historical artifacts in native artifact storage;
  • route metrics into the native metrics representation;
  • preserve valid cache fingerprints;
  • validate the migrated data; and
  • require operators to opt in by running the migration, with the API server
    refusing to start when migration has not completed.

The corresponding migration and post-migration test cases
are currently marked as not automated.

Original implementation behavior (historical baseline)

There is no MLMD-to-native data migration or startup-completion gate in the current
MLMD-removal implementation.

On upgrade:

  1. Historical execution, event, artifact, metric, and cache metadata remains in
    MLMD.
  2. The new native Task and Artifact APIs have no corresponding rows.
  3. The API server's normal
    AutoMigrate
    creates/reconciles the new tables, but it neither imports the MLMD data nor records
    that a validated data migration occurred.
  4. The API server can start and report healthy even though historical runtime
    metadata is absent from the APIs now used by the UI, driver, launcher, and cache
    path.

This creates an additional artifact-access failure mode. Authenticated artifact
requests perform an exact URI lookup through the native Artifact API. If no row is
found, the frontend server's
artifact-then-prefix fallback
can establish ownership only when the object key encodes
private-artifacts/<namespace>/. Historical artifacts using an unnamespaced root,
including the shipped minio://mlpipeline/v2/artifacts
default or another non-canonical layout, cannot use that fallback. In an auth-enabled
deployment the request is correctly denied because ownership cannot be established,
even though the artifact and its ownership evidence still exist in MLMD.

Migrating trusted ownership metadata populates historical native records; it does
not authorize arbitrary object reads. The current master validator also requires
a namespace prefix, but the replacement content boundary in #14031 must preserve
already-authorized roots without requiring object moves or native registration.
It may authorize a constrained historical locator using trusted storage authority
without an Artifact API row. Neither a metadata miss nor an unnamespaced URI
is itself an access grant.

Reproduction

  1. Install a KFP version that still uses MLMD for runtime metadata.
  2. Run V2 pipelines that collectively include:
    • ordinary input and output artifacts;
    • metrics and visualization artifacts;
    • a cacheable component;
    • nested DAGs, loops/iterations, conditions, and an exit handler; and
    • at least two namespaces for multi-user validation.
  3. Include an artifact stored below a historical URI such as
    minio://mlpipeline/v2/artifacts/... that does not encode
    private-artifacts/<namespace>/.
  4. Confirm the completed executions, events, artifacts, and cache metadata exist in
    MLMD.
  5. Upgrade to the MLMD-removal build without running a data migration.
  6. Observe that the API server starts successfully.
  7. Through the native APIs and UI, inspect the historical run graph, task details,
    inputs/outputs, metrics, relationships, visualizations, and artifact downloads.
  8. Submit an equivalent pipeline that should reuse the historical completed cache
    entry.

Expected behavior: the upgrade is blocked until migration completes, or all
historical metadata remains available and correctly authorized after a supported
migration.

Current behavior: native records are absent; historical views and cache behavior can
be incomplete; artifacts with namespace-less roots remain rejected even with a migrated row,
unless a separately supported storage-ownership solution is delivered.

User and operator impact

  • Historical run graphs may appear empty or incomplete.
  • Task state, hierarchy, parameters, inputs, and outputs may be missing.
  • Artifacts and metrics may disappear from run, artifact, visualization, and compare
    views.
  • Artifact preview, visualization, and download may fail.
  • Producer/consumer and input/output relationships may be lost.
  • Previously valid completed cache entries may stop producing cache hits.
  • An installation may accept new native records while leaving its old runtime history
    stranded in MLMD.
  • Operators may discover the incompatible state only after the upgraded deployment is
    serving traffic because table creation alone does not prove migration completion.

This is primarily a metadata availability and upgrade-integrity problem. Object-store
payloads may still exist, but users lose the supported KFP metadata and authorization
path required to locate, interpret, visualize, or safely retrieve them.

Required implementation

1. Deliver an explicit migration mechanism

Provide either:

  • a documented operator-run command/job/script; or
  • an explicitly enabled, one-time API-server migration mode.

The migration must:

  • support the database and deployment configurations covered by the KFP upgrade
    policy;
  • document required backups and prerequisites, including the availability of MLMD;
  • be idempotent or safely resumable after interruption;
  • avoid duplicate tasks, artifacts, metrics, and relationships when rerun;
  • report progress, source/destination counts, skipped records, and validation errors;
  • avoid modifying artifact object data unless explicitly necessary; and
  • write a durable migration-version/completion marker only after validation succeeds.

A dry-run or validation-only mode is strongly recommended.

2. Migrate task and run-time execution metadata

Convert relevant MLMD execution/context data into native tasks while preserving, as
applicable:

  • run and namespace association;
  • task identity, name, display name, and parent-child hierarchy;
  • task type and type-specific attributes;
  • creation, start, and finish timestamps;
  • state, status metadata, and state history;
  • input/output parameters, pod references, and scope information; and
  • the stable identities needed by the native APIs and cache path.

Cover the execution/task forms described by the removal design: root DAG, generic
DAG, runtime/container, loop, loop iteration, condition, condition branch, and exit
handler. Include the documented exit-handler-* detection case where MLMD does not
otherwise identify that type declaratively.

3. Preserve cache correctness

Migrate cache fingerprints with their owning task metadata. As required by the
design, retain a ContainerExecution fingerprint only when the source execution is
complete. Failed, cancelled, or incomplete executions must not become valid cache
entries.

An equivalent post-upgrade pipeline should reuse an eligible migrated cache entry,
while ineligible source executions must remain cache misses.

4. Migrate artifacts, metrics, and relationships

For relevant MLMD artifacts, preserve:

  • namespace and run ownership;
  • URI and stable identity, or an auditable old-to-new identity mapping;
  • name, schema/type, lifecycle state, timestamps, and custom metadata; and
  • information required for current artifact providers and visualization behavior.

Route metric artifact types according to the native metrics storage/API contract
rather than treating them as ordinary downloadable artifacts.

Convert MLMD events into native artifact-task relationships while preserving:

  • producer/consumer task and run identity;
  • artifact key;
  • input versus output direction; and
  • iterator, OneOf, task-final-status, and other relationship semantics supported by
    the native API.

Every migrated relationship must reference an existing migrated run, task, and
artifact/metric in the same authorized namespace.

5. Validate before declaring completion

Before writing the completion marker, validate at least:

  • source and destination counts, with documented exclusions;
  • task-to-run and parent-task referential integrity;
  • artifact/metric-to-task relationship integrity;
  • namespace consistency and absence of cross-namespace relationships;
  • cache-fingerprint eligibility;
  • metric-versus-artifact routing;
  • stable identity/deduplication invariants; and
  • orphaned or unsupported MLMD records.

Validation failures must be actionable, leave the migration incomplete, and not
silently discard unsupported data.

6. Add an API-server startup gate

Startup must distinguish these states:

  1. Fresh/empty installation: start normally.
  2. Existing MLMD-backed installation without migration: refuse to start.
  3. Migration started but incomplete or failed: refuse to start.
  4. Expected migration version completed and validated: start normally.

The gate must use a durable version/completion marker plus any necessary schema/data
inspection. The existence of the new tables, or the presence of some newly created
rows, is not evidence that historical data was migrated.

The startup error should state:

  • that MLMD-to-native migration is required;
  • the expected migration version;
  • how to run, resume, or validate it;
  • that the operator should verify the required backup; and
  • where to find upgrade and rollback documentation.

Security requirements

  • Derive task/artifact ownership from trusted MLMD contexts/associations and existing
    KFP run metadata, never from a caller-supplied namespace alone.
  • Persist the correct namespace on every migrated record and relationship.
  • Preserve tenant boundaries and the existing SubjectAccessReview/RBAC behavior.
  • Fail closed when the required authenticated storage authority cannot be established.
    Metadata API availability is not a universal prerequisite for the separately
    authorized historical content path defined in feat(api): move artifact authorization and content access behind a backend API #14031.
  • Do not grant object access from arbitrary Artifact API misses, caller-created
    provenance, or unnamespaced historical URIs. Preserve authorized existing roots
    through trusted storage authority, without reintroducing runtime MLMD.
  • Run migration with explicitly documented administrative privileges and least
    privilege where practical.
  • Do not log credentials, signed query parameters, or secrets embedded in artifact
    URIs or provider metadata.
  • Include multi-user tests proving that one namespace cannot list, inspect, visualize,
    or retrieve another namespace's migrated records.

Acceptance criteria

  • A supported migration command/job or explicit one-time migration mode is
    included and documented.
  • Migration is idempotent or safely resumable and does not create duplicates.
  • Existing MLMD executions are represented by native tasks with correct run,
    namespace, type, hierarchy, state, timing, parameters, and relevant attributes.
  • Only eligible completed executions retain cache fingerprints.
  • Existing non-metric artifacts are available through the native Artifact API.
  • Existing metrics are available through the native metric paths and frontend
    views.
  • Artifact-task relationships preserve keys, direction, and supported relationship
    types.
  • Historical run graphs and task details render correctly after migration.
  • Historical artifacts can be listed, previewed, visualized, and downloaded after
    migration, including authorized non-prefix historical URIs. Migrated ownership
    rows alone do not grant object access; verify the independent storage authority
    and supported historical locators without native IDs.
  • Equivalent pipelines reuse eligible migrated cache entries.
  • Validation failures do not write the completion marker.
  • The API server refuses to start for an existing unmigrated, partially migrated,
    or failed-migration installation.
  • The API server starts for a fresh installation and for an installation with the
    expected successfully validated migration version.
  • Startup failure contains actionable backup, migration, validation, and recovery
    guidance.
  • Multi-user tests prove namespace isolation for all migrated records and artifact
    access paths.
  • Upgrade, validation, backup, and rollback documentation is published.

Test plan

Create sanitized pre-upgrade database/MLMD fixtures containing:

  • completed, failed, running, and cached executions;
  • root/nested DAGs, loops and iterations, conditions and branches, and an exit handler;
  • ordinary artifacts, visualization metadata, and metrics;
  • producer/consumer relationships with the supported I/O types;
  • multiple namespaces; and
  • artifacts using both private-artifacts/<namespace>/... and historical
    unnamespaced URI layouts.

Automate the following:

  1. Run migration and compare source inventory with destination records and reported
    exclusions.
  2. Run migration a second time and verify no duplicates or destructive changes.
  3. Interrupt migration and verify safe resume without a premature completion marker.
  4. Verify historical and newly created runs side by side through native APIs and UI.
  5. Verify historical artifact list, preview, visualization, and download behavior,
    independently checking metadata visibility and object access. Start with actual
    2.18 credentials/roots and no deferred artifact-adoption resources.
  6. Verify cache hits from completed executions and cache misses from ineligible
    executions.
  7. Verify native metrics retrieval and rendering.
  8. Verify cross-namespace list, get, visualization, and download requests are denied.
  9. Exercise the startup matrix: fresh, unmigrated, partially migrated, failed, wrong
    migration version, and successfully migrated.
  10. Restore the documented backup and verify the prior MLMD-backed release remains
    operable.

Execution transition and 2.18 deferral decision (October 6, 2026)

TaskService authentication/backport PR #14707 is deferred from 2.18; release decision and tradeoffs are recorded in #14409 and #14421. The 2.18 line retains its existing TaskService behavior and exposure. The 3.0 line removes that service and authorizes the native task/cache APIs, but this does not make an in-place upgrade automatically safe.

Track the execution-transition acceptance alongside the historical-data migration in this issue. No particular automatic migration implementation is mandated by this decision, and the 2.18 prototype is not a shipped or verified 3.0 solution. Keep this issue open until both the supported data migration and the supported execution-transition contract have evidence, or link a separately owned release-blocking execution-transition issue before closing this one.

Required execution-transition decisions and verification:

  • Define and validate treatment of running, pending and suspended old workflows, including future tasks, lifecycle/exit handlers and outstanding cache registrations when old APIs/MLMD are removed.
  • Define and test retries of historical failed runs. Preserve completed nodes, outputs and identities where migration is supported; otherwise provide an explicit preflight rejection or documented alternative, not a silent fresh-run replay.
  • Cover newly submitted native V2 IR runs, recurring runs, re-submitted saved packages, V1/V2-compatible/precompiled Argo packages and custom driver/launcher images. State unsupported cases explicitly; a new launch is not proof of a new client.
  • Coordinate old/new API and controller replicas and in-flight create/retry operations so that supported old clients cannot unexpectedly appear after cutoff. Do not reopen anonymous APIs to preserve compatibility.
  • Verify historical cache eligibility and retained ownership as well as active-client behavior. Disclose independently changed cache fingerprints and resulting re-execution; neither historical data import nor an empty-cache fallback alone proves preserved behavior.
  • Publish preflight, operator-visible progress/blockers, interruption/recovery and rollback guidance for the chosen upgrade contract. Demonstrate it with actual old-to-new, multi-namespace runtime/upgrade tests before claiming support.

Immediate hard enforcement can fail old work; cache-miss/no-op compatibility can repeat costly or side-effectful tasks; preserving cache behavior during automatic drain requires additional coordination. Namespace-local drain is one possible approach, not an approved universal compatibility promise. Do not transfer unfinished 2.18 migration machinery wholesale to the different native 3.0 architecture.

Scope boundaries and related work


Love this idea? Give it a 👍.

Activity

  1. github-actions commented on Aug 13, 2026

    @github-actions

    🤖 AI Issue Quality Review

    ⚠️ Validation Failed: Issue title must follow the correct format: <type>(<area>): <title contents> where type is bug, chore, or feature.

  2. Priyanshu-u07 commented on Aug 13, 2026

    @Priyanshu-u07
    Member

    /assign

  3. ayushagarwalhere commented on Sep 8, 2026

    @ayushagarwalhere

    /assign

  4. ayushagarwalhere commented on Sep 13, 2026

    @ayushagarwalhere

    I’ve implemented the core architecture for the MLMD-to-native migration described in this issue and opened the PR here:

    PR: [#186 — feat(backend): add MLMD-to-native migration and startup gate]
    @jeffspahr, could you please review the changes and the overall migration approach?

    The implementation includes:

    • MLMD → native runs/tasks/artifacts/metrics/relationships conversion
    • Idempotent persistence with semantic validation
    • Migration lifecycle, durable completion marker, and validation
    • Legacy MLMD schema detection
    • API-server startup gate
    • Cache fingerprint eligibility
    • Namespace ownership and cross-namespace validation
    • Migration command and documentation
    • Unit, lifecycle, persistence, converter, API, and production-like fixture coverage

    There are still some deployment-level acceptance tests that I have not been able to verify in my current environment, particularly:

    • Real old-KFP → new-KFP upgrade with MLMD
    • Actual cache hit/miss through the runtime cache path
    • Historical artifact preview/download
    • Frontend visualization
    • Full PostgreSQL/MySQL + MLMD deployment validation
    • Additional multi-user API authorization coverage
    • Richer relationship scenarios (OneOf, iterator, collected input, final-status, etc.)

    The core architecture and implementation are in place. I’d appreciate a review of the current approach first, and based on the feedback I can add or adjust the remaining integration/acceptance tests accordingly.

  5. Priyanshu-u07 commented on Sep 14, 2026

    @Priyanshu-u07
    Member

    Hi @ayushagarwalhere, just wanted to let you know that I’ve been assigned to this issue since August and have been working on it locally. I was waiting for #13986 to merge before opening a PR against kubeflow/pipelines.

    I’ll continue with my implementation once #13986 is merged. Thanks!

  6. ayushagarwalhere commented on Sep 14, 2026

    @ayushagarwalhere

    Hi @Priyanshu-u07 , thanks for letting me know, and apologies for assuming that you might have forgotten about the assigned issue since it had been about a month. I wasn’t aware that you had already been working on it locally.

    I’ve actually implemented the core migration architecture on HumairAK/data-science-pipelines: mlmd-removal-rebase branch, where the #13986 changes are already present. I opened the implementation as [HumairAK/data-science-pipelines#186] so that the migration work can be reviewed against the #13986 changes without waiting for the merge.

    I’d be happy to coordinate on this with you. If you’ve already been working on a different approach locally, I’d also be interested in comparing the two implementations once #13986 lands.

  7. Priyanshu-u07 commented on Sep 14, 2026

    @Priyanshu-u07
    Member

    No need to apologise @ayushagarwalhere. For future issues a quick comment before starting helps avoid overlap.

    Rather than duplicating effort, I'd suggest I take the validation and acceptance side: extending your TestProductionLikeUpgradeFixture into a full pre-upgrade MLMD fixture set (all task forms, both URI layouts, two namespaces, eligible vs ineligible cache executions), the real old-KFP → new-KFP upgrade, cache hit/miss through the runtime cache path, cross-namespace isolation, the startup-state matrix, and backup/restore. Those are the items you listed as unverified, and they're what upgrade-test.yml is gated on in #13986. KFP_ENABLE_MLMD_UPGRADE_TESTS is off there, with a TODO pointing at this issue.

    I have an MLMD-backed KFP running on kind locally and pipelines populating metadb, so I can capture the fixture data directly. That's the environment gap you mentioned. I'll start on that now and pick up the deployed upgrade test once #13986 lands and CI can run it.

    @jeffspahr does that split work for you and could HumairAK#186 use Part of #14029 rather than Fixes when it's re-targeted upstream, so the issue stays open for the validation half?

  8. Priyanshu-u07 commented on Sep 22, 2026

    @Priyanshu-u07
    Member

    Fixture set update. @ayushagarwalhere flagging early since it affects the converter.

    I captured a real MLMD dataset from a KFP 2.17.0 deployment on kind: 311 executions covering loops, nested loops, iterations, conditions, an exit handler, cached/failed/cancelled executions, metrics, and the unnamespaced minio://mlpipeline/v2/artifacts/... layout.

    KFP distinguishes task forms through these execution properties (declared in backend/src/v2/metadata/client.go), with row counts from the capture:

    Property Rows Marks Read by converter.go
    total_dag_tasks 168 DAG execution no
    iteration_index 79 loop iteration no
    iteration_count 38 loop no
    image/pod_name/pod_uid 130 container execution no
    artifact_producer_task 77 producer relationship no

    taskType() classifies from a task_type property instead, which KFP never writes. There are 0 rows in the capture and 0 hits across backend/src/ on release-2.18. Its fallback matches the execution type name, but MLMD stores only system.DAGExecution and system.ContainerExecution.

    So loop, loop iteration, condition and condition branch fall through to DAG. Root does too, since there's no ROOT case. And exit handlers are DAG executions, so the system.DAGExecution case returns DAG before the exit-handler- prefix case is reached, and that case returns RUNTIME rather than EXIT_HANDLER in any event. Six of the eight forms item 2 requires collapse to DAG.

    The namespace fallback via the system.PipelineRun context is correct, though. Cached executions have an empty namespace and only PipelineRun contexts carry one.

    Separately: are you planning to open HumairAK#186 against kubeflow/pipelines:master? CI hasn't run on it yet and that would let it get reviewed.

  9. Priyanshu-u07 commented on Oct 9, 2026

    @Priyanshu-u07
    Member

    Sharing my approach before opening PRs.

    Scope: In-place upgrades from 2.18 to 3.0 with an automated migration. Export and import covers replacement installations, which is a separate path.

    Approach

    Entry points: A standalone utility admins can run ahead of the upgrade to keep downtime short, plus an automatic, idempotent true-up at API-server startup with no opt-in. The utility has a dry-run mode.

    Startup check: A read-only check runs before any schema change. It detects a 2.18 database and confirms the metadata connection first, so schema migration never alters a database the server then cannot migrate. The server migrates in maintenance mode and exits non-zero if it cannot.

    Reader: Metadata is read over gRPC, which yields records in the shape the existing conversion code already decodes.

    Cache: Fingerprints of completed executions are preserved, so an equivalent pipeline still gets a cache hit after upgrading. Incomplete, failed and cancelled executions do not become cache entries.

    Metrics: Migrated as native metric artifacts, matching how the runtime stores them today.

    Rolling upgrades: Runs in flight keep using 2.18 driver and launcher pods, which continue writing metadata after the first pass. Holding maintenance mode until they finish could take hours, so the server leaves maintenance after the first full pass and keeps truing up in the background until every run started under 2.18 has finished. Those runs are terminal by then, and the design specifies that tasks of a terminal run are not updated, so the true-up writes through the store.

    Completion record: One row in the existing migration status table records completion once the checklist passes and those runs have finished. Without it, every startup would still need the metadata service in order to confirm completeness, long after it has been removed. Resume uses deterministic identities, so no new table is needed.

    Root DAG state: Root DAG executions remain in a running state in metadata by design, so a root task's state is taken from its run's recorded state instead.

    Acceptance: Re-enable the paused upgrade tests. Their post-upgrade checks currently confirm only that runs, experiments and schedules are listable, so I'll extend them with task, artifact, lineage and artifact-download assertions against a fixture containing loops, conditions and an exit handler.

    Docs: An operator guide covering backup first, optionally running the utility ahead of time, then upgrading. Rollback is restoring the backup.

    One open question: May the per-record conversion helpers for task type, state, parameters and artifact bindings move into a shared package? In-place needs different assembly around them, since runs keep their identity and stay retryable, but the conversions themselves are the same. One case worth covering either way: 2.18 records workspace importers as a fourth execution type beyond DAG, container and importer, which a shared helper should map to IMPORTER.

    @jeffspahr could you review this before I start? Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions