This change enables floaty delete to accept request-ids (UUID format) in addition to hostnames. When a request-id is detected, floaty will: 1. Cancel pending ondemand requests by marking status as 'deleted' 2. Move any already-provisioned VMs to the termination queue Implementation: - Modified Pooler.delete to detect UUID format and use ondemandvm endpoint - Updated command syntax and examples to document request-id support - Added comprehensive tests for request-id deletion - Fixed Ruby 3.1+ compatibility by adding abbrev and base64 gems Fixes issue where users had no way to cancel ondemand requests or bulk-delete VMs from a completed request.
6 KiB
Floaty Delete Request-ID Feature
Branch: P4DEVOPS-floaty-delete-request-id
PR Link: https://github.com/puppetlabs/vmfloaty/pull/new/P4DEVOPS-floaty-delete-request-id
Date: December 19, 2025
Problem Statement
Previously, floaty delete only supported deleting VMs by hostname. Users had no way to:
- Cancel pending ondemand VM requests before they complete
- Bulk-delete all VMs from a completed ondemand request in one command
This required users to either:
- Wait for unwanted requests to complete, then delete VMs individually
- Manually track which VMs belonged to which request
- Use the vmpooler API directly via curl
Solution
Extended floaty delete to accept request-ids (UUID format) in addition to hostnames.
Behavior
When floaty delete <request-id> is called:
- For pending requests: Marks the request status as 'deleted' to cancel provisioning
- For completed requests: Moves all provisioned VMs to the termination queue
- Mixed input: Can handle both hostnames and request-ids in the same command
UUID Detection
The implementation uses a regex pattern to detect UUID format:
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
When a UUID is detected, floaty uses the DELETE /ondemandvm/:requestid endpoint instead of the regular DELETE /vm/:hostname endpoint.
Implementation Details
Files Changed
-
lib/vmfloaty/pooler.rb - Modified
Pooler.deletemethod- Added UUID detection logic
- Routes to appropriate endpoint based on input format
- Maintains backward compatibility with hostname deletion
-
lib/vmfloaty.rb - Updated command documentation
- Added new syntax example for request-id deletion
- Updated description to mention ondemand request cancellation
-
spec/vmfloaty/pooler_spec.rb - Added comprehensive tests
- Test single request-id deletion
- Test multiple request-id deletion
- Test mixed hostname and request-id deletion
-
Gemfile - Added Ruby 3.1+ compatibility gems
abbrev- Required by commander gem in Ruby 3.1+base64- Required by spec_helper in Ruby 3.1+
Code Changes
Before:
def self.delete(verbose, url, hosts, token, _user)
raise TokenError, 'Token provided was nil.' if token.nil?
conn = Http.get_conn(verbose, url)
conn.headers['X-AUTH-TOKEN'] = token if token
response_body = {}
hosts.each do |host|
response = conn.delete "vm/#{host}"
res_body = JSON.parse(response.body)
response_body[host] = res_body
end
response_body
end
After:
def self.delete(verbose, url, hosts, token, _user)
raise TokenError, 'Token provided was nil.' if token.nil?
conn = Http.get_conn(verbose, url)
conn.headers['X-AUTH-TOKEN'] = token if token
response_body = {}
hosts.each do |host|
# Check if this looks like a request-id (UUID format)
if host =~ /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
# This is a request-id, use the ondemandvm endpoint
response = conn.delete "ondemandvm/#{host}"
res_body = JSON.parse(response.body)
response_body[host] = res_body
else
# This is a hostname, use the vm endpoint
response = conn.delete "vm/#{host}"
res_body = JSON.parse(response.body)
response_body[host] = res_body
end
end
response_body
end
Usage Examples
Delete a single ondemand request
floaty delete e3ff6271-d201-4f31-a315-d17f4e15863a
Delete multiple requests
floaty delete e3ff6271-d201-4f31-a315-d17f4e15863a,a1b2c3d4-e5f6-7890-abcd-ef1234567890
Delete mixed hostnames and requests
floaty delete myvm1,e3ff6271-d201-4f31-a315-d17f4e15863a,myvm2
Get request-id from ondemand request
# When you create an ondemand request, you get a request_id
floaty get centos-7-x86_64=5 --ondemand
# Output includes: "request_id": "e3ff6271-d201-4f31-a315-d17f4e15863a"
# Later, cancel it or delete completed VMs
floaty delete e3ff6271-d201-4f31-a315-d17f4e15863a
Testing
Test Coverage
All tests pass (142 examples, 0 failures):
bundle exec rspec
# Finished in 0.90126 seconds
# 142 examples, 0 failures
# Line Coverage: 47.72% (534 / 1119)
New Tests Added
-
Single request-id deletion
- Verifies correct endpoint is called
- Validates response format
-
Multiple request-id deletion
- Tests batch deletion
- Ensures each request uses correct endpoint
-
Mixed hostname and request-id deletion
- Validates intelligent routing
- Confirms backward compatibility
Backend API Support
This feature leverages the existing vmpooler API endpoint:
DELETE /api/v3/ondemandvm/:requestid
API Behavior:
- Sets request status to 'deleted' in Redis
- Moves any provisioned VMs from
runningtocompletedqueue - Returns
{"ok": true}on success - Returns 404 if request not found
Reference: vmpooler API v3 docs
Backward Compatibility
✅ Fully backward compatible - All existing functionality preserved:
- Regular hostname deletion still works
- Command syntax unchanged for hostnames
- All existing tests continue to pass
- No breaking changes to API
Benefits
- Improved UX: Users can cancel unwanted requests easily
- Cost Savings: Avoid provisioning VMs that won't be used
- Cleanup: Bulk-delete all VMs from a request in one command
- Consistency: Matches ABS behavior (floaty already supports JobID deletion)
Next Steps
- ✅ Create PR: https://github.com/puppetlabs/vmfloaty/pull/new/P4DEVOPS-floaty-delete-request-id
- Get code review from vmfloaty maintainers
- Address any feedback
- Merge to main branch
- Create new vmfloaty release with this feature
Related Work
- Inspired by existing ABS JobID deletion support
- Complements ondemand VM provisioning feature added in earlier versions
- Part of broader effort to improve vmpooler queue reliability (P4DEVOPS-8567)