Skip to content

Conversation

@peytonr18
Copy link
Contributor

@peytonr18 peytonr18 commented Oct 24, 2025

Summary

This PR decouples the health reporting logic from the provisioning process, enabling independent retry capabilities and more flexible failure handling. Previously, provisioning and health reporting were tightly coupled—if reporting failed, the entire provisioning would be marked as failed. Now, provisioning writes state files that can be reported separately, allowing retries without re-provisioning.

Changes

Core Library Changes

libazureinit/src/error.rs

  • Added AlreadyReported error variant for idempotent reporting
  • Added NoProvisioningState error when no state files exist
  • Added InvalidStateFile error for malformed state files

libazureinit/src/health.rs

  • report_ready_from_state() - Reports provisioning success by reading from .provisioned state file
  • report_failure_from_state() - Reports provisioning failure by reading from .failed state file
  • load_state_file() - Loads config and state file with proper locking and validation
  • All reporting functions now check for "REPORTED" marker to prevent duplicate reports

libazureinit/src/status.rs

  • mark_provisioning_failure() - Creates .failed state file with encoded error report
  • has_been_reported() - Checks if state file has been reported (contains "REPORTED" marker)
  • mark_reported() - Appends "REPORTED" marker to state file after successful report
  • Made get_provisioning_dir() public for external access
  • Enhanced mark_provisioning_complete() with file locking for thread safety
  • Added comprehensive unit tests for all new functions

libazureinit/src/lib.rs

  • Exported new public functions: report_ready_from_state(), report_failure_from_state()
  • Exported new status functions: mark_provisioning_failure(), mark_reported()
  • Made status module public

CLI Changes (src/main.rs)

New report Subcommand

azure-init report auto       # Auto-detect state and report
azure-init report ready      # Report success from .provisioned file
azure-init report failure    # Report failure from .failed file

New --report Flag

azure-init --report          # Provision AND report in one step

Updated Provisioning Flow

  • Success Creates {vm_id}.provisioned file with success report (no immediate Azure reporting)
  • Failure: Creates {vm_id}.failed file with error report (no immediate Azure reporting)

Updated clean Command

  • Now removes both .provisioned and .failed files

Test Changes (tests/cli.rs)

  • Updated setup_clean_test() to create both .provisioned and .failed files
  • Updated clean tests to verify both file types are removed
  • help_shows_report_command() - Verifies report command in help text
  • report_help_shows_subcommands() - Verifies report subcommands exist
  • report_auto_fails_without_state_files() - Verifies graceful failure
  • report_ready_fails_without_provisioned_file() - Verifies error handling
  • report_failure_fails_without_failed_file() - Verifies error handling

Flow Diagram

New Provisioning and Reporting Flow

┌─────────────────────────────────────────────────────────────┐
│                    Provisioning Phase                       │
└─────────────────────────────────────────────────────────────┘

    ┌──────────────┐
    │  azure-init  │ ← Provisions the VM
    └──────┬───────┘
           │
           ├─── Success ────────┐
           │                    ↓
           │          ┌──────────────────┐
           │          │ {vm_id}.provisioned│ ← Contains success report
           │          └──────────────────┘
           │
           └─── Failure ────────┐
                                ↓
                      ┌──────────────────┐
                      │  {vm_id}.failed  │ ← Contains error report
                      └──────────────────┘

┌─────────────────────────────────────────────────────────────┐
│                     Reporting Phase                         │
│              (Can be retried independently)                 │
└─────────────────────────────────────────────────────────────┘

    ┌────────────────────────┐
    │ azure-init report auto │ ← Auto-detects state file
    └───────────┬────────────┘
                │
                ├─── Reads .failed ────────┐
                │                          ↓
                │              ┌────────────────────────┐
                │              │  Reports failure to   │
                │              │  Azure Health Endpoint│
                │              └───────────┬────────────┘
                │                          │
                │                          ↓
                │              Appends "REPORTED" to .failed
                │
                └─── Reads .provisioned ───┐
                                           ↓
                               ┌────────────────────────┐
                               │  Reports success to   │
                               │  Azure Health Endpoint│
                               └───────────┬────────────┘
                                           │
                                           ↓
                               Appends "REPORTED" to .provisioned

┌─────────────────────────────────────────────────────────────┐
│                 Alternative: Inline Mode                    │
└─────────────────────────────────────────────────────────────┘

    ┌─────────────────────┐
    │ azure-init --report │ ← Provision AND report in one step
    └──────────┬──────────┘
               │
               ├─── Provisions VM
               │         │
               │         ├─── Success: Creates .provisioned + reports + marks REPORTED
               │         │
               │         └─── Failure: Creates .failed + reports + marks REPORTED
               │
               └─── Both phases complete in single execution

Usage Examples

Scenario 1: Decouple Provisioning and Reporting (Recommended)

# Step 1: Provision (creates state file)
azure-init

# Step 2: Report to Azure (can be retried if network fails)
azure-init report auto

Scenario 2: Provision and Report Together

# Single command does both (legacy-style behavior)
azure-init --report

Scenario 3: Manual Report Commands

# Report success explicitly
azure-init report ready

# Report failure explicitly
azure-init report failure

Scenario 4: Clean State Files

# Remove all state files
azure-init clean

# Remove state files AND logs
azure-init clean --logs

Breaking Changes

The default behavior (running azure-init alone) maintains backward compatibility:

  • Provisioning runs as before
  • State files are created (new behavior, but non-breaking)
  • Reporting is now optional via --report flag or report subcommand

Users relying on immediate health reporting should:

  • Add --report flag to existing commands, OR
  • Follow provisioning with azure-init report auto

Related Issues

Closes #263

…logic and failure handling. Provisioning now writes state files (.provisioned/.failed) that can be reported independently via new report subcommand or --report flag.
@peytonr18 peytonr18 marked this pull request as ready for review October 24, 2025 21:18
}

#[test]
fn test_mark_provisioning_failure() {
Copy link

@KsenijaS KsenijaS Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are tests not in a separate file, under tests folder?

@peytonr18 peytonr18 changed the title Decouple Health Reporting from Provisioning [Not For Review]: Decouple Health Reporting from Provisioning Oct 27, 2025
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] Add report-ready & report-failure flag to Azure-init CLI

2 participants