Skip to content

refactor: extract KVP into standalone libazureinit-kvp crate with layered architecture#287

Open
peytonr18 wants to merge 1 commit intoAzure:mainfrom
peytonr18:probertson/kvp-layered-architecture
Open

refactor: extract KVP into standalone libazureinit-kvp crate with layered architecture#287
peytonr18 wants to merge 1 commit intoAzure:mainfrom
peytonr18:probertson/kvp-layered-architecture

Conversation

@peytonr18
Copy link
Contributor

Summary

Extracts KVP into a standalone crate, libazureinit-kvp, and replaces the legacy libazureinit::kvp module with a layered, trait-generic architecture.

This keeps azure-init's tracing-based KVP emission behavior while making KVP reusable for external distros without pulling in the full azure-init stack.

  • Replaces libazureinit/src/kvp.rs (902 lines) with a new workspace crate: libazureinit-kvp.
  • Moves KVP from async channel/background writer semantics to synchronous flock-guarded I/O.
  • Preserves existing tracing integration in azure-init while simplifying runtime lifecycle management.
  • Adds architecture and API documentation for internal and external consumers.

What Changed

New crate: libazureinit-kvp

Introduces a 4-layer design plus top-level client wiring:

  • Layer 0: KvpStore trait
    • HyperVKvpStore (production pool-file implementation)
    • InMemoryKvpStore (test double)
  • Layer 1: DiagnosticsKvp<S>
    • typed diagnostics
    • Azure 1022-byte value chunking support
  • Layer 2: TracingKvpLayer<S>
    • tracing_subscriber::Layer adapter
    • handles tracing events/spans and health_report passthrough
  • Layer 3: ProvisioningReport
    • typed accessor for PROVISIONING_REPORT
  • Top-level: Kvp<S> client to wire all layers together

Legacy module removed

  • Deletes libazureinit/src/kvp.rs; functionality now lives in libazureinit-kvp.

libazureinit integration simplified

  • libazureinit/src/logging.rs
    • removes old KVP wrapper/lifecycle plumbing (JoinHandle, CancellationToken, halt(), close())
    • setup_layers now returns only Box<dyn Subscriber + Send + Sync>
  • src/main.rs
    • removes KVP shutdown orchestration block
    • no explicit async KVP lifecycle handling needed

Dependency updates

  • libazureinit drops direct fs2/sysinfo usage for KVP internals
  • adds path dependency on libazureinit-kvp
  • workspace now includes libazureinit-kvp

Docs

  • Adds doc/kvp_design.md (design rationale + architecture)
  • Rewrites doc/libazurekvp.md (API/reference)
  • Aligns docs with implemented key format and ProvisioningReport API
  • Documents/reporting behavior for long health_report values

Why

  • External reuse: other distros can consume KVP directly with minimal dependencies.
  • Separation of concerns: storage, diagnostics, tracing adapter, and provisioning report logic are decoupled.
  • Simpler lifecycle: no channel draining, shutdown tokens, or background writer task ownership.
  • Testability: each layer can be tested independently; in-memory testing is straightforward.

Behavioral Notes

  • KVP writes are now synchronous (flock + write + unlock) rather than buffered async channel writes.
  • Long diagnostic/report values are chunked to account for Azure's read limits.
  • health_report to PROVISIONING_REPORT path preserves long values through chunked writes.

Architecture

┌─────────────────────────────────────────────────┐
│ Kvp<S> (top-level client, wires layers)         │
├─────────────────────────────────────────────────┤
│ Layer 3: ProvisioningReport                     │
│          Typed accessor for PROVISIONING_REPORT │
├─────────────────────────────────────────────────┤
│ Layer 2: TracingKvpLayer<S>                     │
│          tracing_subscriber::Layer adapter      │
├─────────────────────────────────────────────────┤
│ Layer 1: DiagnosticsKvp<S>                      │
│          Typed diagnostic events + chunking     │
├─────────────────────────────────────────────────┤
│ Layer 0: KvpStore trait                         │
│   ┌──────────────────┐   ┌─────────────────────┐│
│   │ HyperVKvpStore   │   │ InMemoryKvpStore    ││
│   │ (production)     │   │ (test double)       ││
│   └──────────────────┘   └─────────────────────┘│
└─────────────────────────────────────────────────┘

See doc/kvp_design.md for design rationale and doc/libazurekvp.md for API details.

Fixes #239. Supersedes #286.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[RFE] Support Concurrent KVP Telemetry

1 participant