Class: Pvectl::Services::ResourceDelete

Inherits:
Object
  • Object
show all
Defined in:
lib/pvectl/services/resource_delete.rb,
sig/pvectl/services/resource_delete.rbs

Overview

Orchestrates deletion of VMs and containers.

Handles validation, force-stop of running resources, and async/sync modes.

Examples:

Delete stopped VMs

service = ResourceDelete.new(vm_repository: vm_repo, container_repository: ct_repo, task_repository: task_repo)
results = service.execute(:vm, [vm1, vm2])

Delete with force (stops running VMs first)

service = ResourceDelete.new(..., options: { force: true })
results = service.execute(:vm, [running_vm])

Constant Summary collapse

DEFAULT_TIMEOUT =

Returns:

60

Instance Method Summary collapse

Constructor Details

#initialize(vm_repository:, container_repository:, task_repository:, options: {}) ⇒ ResourceDelete

Creates a new ResourceDelete service.

Parameters:

  • VM repository

  • Container repository

  • Task repository

  • (defaults to: {})

    Options (force, keep_disks, purge, timeout, async, fail_fast)

  • (defaults to: {})


26
27
28
29
30
31
# File 'lib/pvectl/services/resource_delete.rb', line 26

def initialize(vm_repository:, container_repository:, task_repository:, options: {})
  @vm_repository = vm_repository
  @container_repository = container_repository
  @task_repository = task_repository
  @options = options
end

Instance Method Details

#build_result(resource, **attrs) ⇒ Models::VmOperationResult, Models::ContainerOperationResult

Builds typed OperationResult for the current resource type.

Parameters:

  • Resource

  • Result attributes

Returns:

  • Typed result



145
146
147
148
149
150
151
# File 'lib/pvectl/services/resource_delete.rb', line 145

def build_result(resource, **attrs)
  if @resource_type == :vm
    Models::VmOperationResult.new(vm: resource, **attrs)
  else
    Models::ContainerOperationResult.new(container: resource, **attrs)
  end
end

#delete_single(resource) ⇒ Models::OperationResult

Deletes a single resource.

Parameters:

  • Resource to delete

Returns:

  • Result



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/pvectl/services/resource_delete.rb', line 58

def delete_single(resource)
  # Check if running
  if resource.status == "running"
    return running_error(resource) unless @options[:force]

    stop_result = stop_resource(resource)
    return stop_result if stop_result.failed?
  end

  # Perform delete
  perform_delete(resource)
rescue StandardError => e
  build_result(resource,
    operation: :delete,
    success: false,
    error: e.message
  )
end

#execute(resource_type, resources) ⇒ Array<Models::OperationResult>

Executes delete operation on resources.

Parameters:

  • :vm or :container

  • Resources to delete

Returns:

  • Results for each resource



38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/pvectl/services/resource_delete.rb', line 38

def execute(resource_type, resources)
  @resource_type = resource_type
  results = []

  resources.each do |resource|
    result = delete_single(resource)
    results << result

    break if @options[:fail_fast] && result.failed?
  end

  results
end

#perform_delete(resource) ⇒ Models::OperationResult

Performs the actual delete operation.

Parameters:

  • Resource

Returns:

  • Result



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/pvectl/services/resource_delete.rb', line 114

def perform_delete(resource)
  repo = repository_for(@resource_type)
  delete_opts = {
    destroy_disks: !@options[:keep_disks],
    purge: @options[:purge] || false,
    force: false
  }

  upid = repo.delete(resource.vmid, resource.node, **delete_opts)

  if @options[:async]
    build_result(resource,
      operation: :delete,
      task_upid: upid,
      success: :pending
    )
  else
    task = @task_repository.wait(upid, timeout: timeout)
    build_result(resource,
      operation: :delete,
      task: task,
      success: task.successful?
    )
  end
end

#repository_for(type) ⇒ Repositories::Vm, Repositories::Container

Returns the appropriate repository for resource type.

Parameters:

  • :vm or :container

Returns:

  • Repository



157
158
159
# File 'lib/pvectl/services/resource_delete.rb', line 157

def repository_for(type)
  type == :vm ? @vm_repository : @container_repository
end

#running_error(resource) ⇒ Models::OperationResult

Returns error for running resource.

Parameters:

  • Resource

Returns:

  • Failed result



81
82
83
84
85
86
87
88
# File 'lib/pvectl/services/resource_delete.rb', line 81

def running_error(resource)
  type_name = @resource_type == :vm ? "VM" : "Container"
  build_result(resource,
    operation: :delete,
    success: false,
    error: "#{type_name} #{resource.vmid} is running. Stop it first or use --force"
  )
end

#stop_resource(resource) ⇒ Models::OperationResult

Stops a running resource.

Parameters:

  • Resource

Returns:

  • Result



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/pvectl/services/resource_delete.rb', line 94

def stop_resource(resource)
  repo = repository_for(@resource_type)
  upid = repo.stop(resource.vmid, resource.node)
  task = @task_repository.wait(upid, timeout: timeout)

  if task.successful?
    build_result(resource, operation: :stop, task: task, success: true)
  else
    build_result(resource,
      operation: :delete,
      success: false,
      error: "Failed to stop: #{task.exitstatus}"
    )
  end
end

#timeoutInteger

Returns configured timeout.

Returns:

  • Timeout in seconds



164
165
166
# File 'lib/pvectl/services/resource_delete.rb', line 164

def timeout
  @options[:timeout] || DEFAULT_TIMEOUT
end