User Tools

Site Tools


syntheses:vps-create-flow

This is an old revision of the document!


VPS Creation / Provisioning Flow

Notes

End-to-end flow: customer clicks Create Server → validation → guest created in DB → HostCommand queued → HostDaemon executes on compute host → VPS starts running.

Repository

  • Source: product/website/ (vps/vps project 1)
  • API layer: Product/website/WebApi/
  • Domain layer: Product/website/Domain/Services/
  • Persistence: Product/website/Persistence/
  • Host commands: Product/website/Domain/Commands/

Flow Summary

# '''HTTP POST /servers''' — ''product/website/WebApi/Controllers/ServersController.Post()''
  Accepts a ''CreateServerDTO'' from the customer via the WebApi REST endpoint.
  Delegates to ''_guestPlanApiService.CreateServer()''.
# '''GuestPlanApiService.CreateServer()''' — ''product/website/WebApi/Services/GuestPlanApiService.cs''
  1. Fetches the customer via ''CustomerResourceService.GetCustomer()''
  2. Checks ''customer.Subscribed'' (payment details verified) — skipped during signup
  3. Calls ''ValidateCreate()'' which checks:
     - ''InvoiceService.CustomerCanPurchase()'' (no overdue invoices)
     - ''customer.GuestCount < customer.GuestLimit''
     - DTO validation via ''ValidationApiService.ValidateOrThrow()''
     - Plan is active (''Plan.ListDisplay'')
  4. Calls ''GetGuestCreationParams()'' to resolve Facility, Plan, OS, Network, etc.
  5. Starts a ''TransactionRunner.Transaction()'' block
  6. Calls ''GuestCreationService.CreateNewGuestDomain()''
  7. Forces ''NHibernateSessionManager.GetSession().Flush()'' to get the ApiId
  8. Processes payment if the guest has a blocking invoice (''TryProcessInvoice()'')
  9. Returns an ''ActionDTO'' with the created guest
# '''GuestCreationService.CreateNewGuestDomain()''' — ''product/website/Domain/Services/GuestCreationService.cs''
  1. Checks ''InvoiceService.CustomerCanPurchase()'' (duplicate check)
  2. Checks ''customer.GuestCount < guestLimit''
  3. Validates private IP if specified (''NetworkService.IsValidPrivateIp()'')
  4. Validates split-nics requires VPC
  5. Calls ''GuestFactory.InitializeNewGuest()'' to create the Guest entity
  6. Calls ''ValidationService.ValidateOrThrow(guest)''
  7. Sets port block, IPv6, split-nics, next duration, SSH keys, etc.
  8. Calls ''GuestProvisioningService.ProvisionNewGuest()''
  9. Optionally assigns a specific private IP (VPC)
  10. Calls ''GuestService.Commit(guest)'' (saves to DB via NHibernate)
  11. Handles referral code logic
  12. Flags as unreviewed at 10th server (fraud prevention)
  13. Calls ''GuestManagementService.CreateGuest()'' to queue the HostCommand
# '''GuestFactory.InitializeNewGuest()''' — ''product/website/Domain/Services/GuestFactory.cs''
  Creates a new Guest entity:
  - Sets ''NetnsEnabled = customer.NetnsCompatible''
  - Generates unique name and hostname
  - Generates rescue password
  - Sets Host/Storage/CurrentCpuModel to ''Unset''
  - Calls ''guest.InitializeFromOperatingSystem()''
  - Calls ''guest.SetPlan(plan, extras)''
  - Sets status to ''GuestStatus.Building''
# '''GuestProvisioningService.ProvisionNewGuest()''' — ''product/website/Domain/Services/GuestProvisioningService.cs''
  1. ''GuestLeaseCreationService.CreateNewLeaseForGuest()'' — creates billing lease
  2. ''HostService.AddGuestToAvailableHost()'' — assigns host
  3. ''NetworkService.AddGuestToNetwork()'' — assigns network
  4. ''GuestService.AssignPrimaryInterfaceToGuest()'' — gets IP, commits guest to DB
  5. ''GuestService.AssignAdditionalInterfaces()'' — additional NICs for VPC
  6. ''BackupScheduleService.SetupGuestBackupSchedule()'' — timemachine config
  7. ''SetupDefaultFirewall()'' — clears firewall rules (empty by default)
# '''GuestManagementService.CreateGuest()''' — ''product/website/Domain/Services/GuestManagementService.cs''
  Creates a ''CreateGuestCommand'' (HostCommand) and calls ''HostCommandService.AddHostCommand()''
  - Sets email password, SSH keys, deployment script, user data

HostCommand Execution (Guest actually starts)

The CreateGuestCommand is persisted in the DB and picked up by the compute host:

# ''HostCommandService.AddHostCommand()'' — ''product/website/Domain/Services/HostCommandService.cs''
  1. Checks for blocking commands via ''HostCommandBroker.GetPossiblyBlockingHostCommands()''
  2. Validates customer has permission
  3. Commits the command to ''HostCommandBroker'' (DB)
# ''HostCommandBroker'' — ''product/website/Persistence/HostCommandBroker.cs''
  Persists the command. The HostDaemon on the compute host polls for new commands.
# '''HostDaemon''' (on compute host)
  Receives the ''CreateGuestCommand'', sets up QEMU/KVM, applies network rules via ''qemu-network/mammothvps.sh'', starts the VM, and marks the command complete.
# ''HostCommandService.WaitForHostCommand()'' — polls with 500ms interval, 30s timeout

Data/State Transitions

  • 'Guest.Status:' Building → (HostCommand completes) → Running
  • 'Guest.Host:' Unset → actual Host entity
  • 'Guest.Storage:' Unset → actual Storage entity
  • 'Guest.Interfaces:' empty → primary + optional additional
  • 'Guest.FirewallRules:' empty (cleared by SetupDefaultFirewall)

Key Entities

  • 'Guest' — the VPS instance entity (NHibernate aggregate root)
  • 'GuestPlan' — the size/plan (CPU, RAM, disk, bandwidth)
  • 'PlanExtras' — additional options (licenses, storage, etc.)
  • 'OperatingSystem' — the OS image (Ubuntu, Debian, etc.)
  • 'Host' — the compute host
  • 'Network' — the network/VPC the guest joins
  • 'HostCommand' — the command sent to the compute host
  • 'CreateGuestCommand' — the specific command for initial creation
  • 'Customer' — the customer account
  • 'Invoice' — billing entity (created/linked during creation)
  • 'Lease' — billing lease for the guest
  • 'BackupDevice' — the backup storage for the guest
  • 'BackupSchedule' — timemachine backup configuration

Failure Points

  • 'Overdue invoice' — customer can't purchase (checked twice: API and domain)
  • 'Guest limit' — GuestCount >= GuestLimit
  • 'No payment details' — customer.Subscribed == false
  • 'Plan not available' — Plan.ListDisplay == false
  • 'No available host' — HostService.AddGuestToAvailableHost() (resource exhaustion)
  • 'No available network' — NetworkService.AddGuestToNetwork()
  • 'No available IP' — InterfaceService.GetNextAvailable()
  • 'HostCommand blocked' — another command running on the same guest
  • 'HostCommand timeout' — 30s wait, 500ms polling
  • 'Payment processing' — InvoiceService.TryProcessInvoice() may fail

Open Questions

  • How does the Guest actually transition from Building to Running? Is it HostDaemon that sets the status, or is there a callback mechanism?
  • What happens if HostDaemon fails during guest creation? Is there a retry/recovery mechanism?
  • How does the billing invoice get finalized? Is there a separate payment flow?
syntheses/vps-create-flow.1784256735.txt.gz · Last modified: by 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki