Skip to content

Commit

Permalink
Add force flag to stop and delete tasks (#22)
Browse files Browse the repository at this point in the history
Unit tests refactoring included

Closes #22
  • Loading branch information
jay7x committed Mar 10, 2024
1 parent 7d6a83e commit 04d01c8
Show file tree
Hide file tree
Showing 12 changed files with 201 additions and 84 deletions.
12 changes: 8 additions & 4 deletions lib/cli_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,10 @@ def create(vm_name, cfg = {})
true
end

def stop(vm_name)
lima_cmd = [@limactl, 'stop', vm_name]
def stop(vm_name, force = false)
lima_cmd = [@limactl, 'stop']
lima_cmd << '--force' if force
lima_cmd << vm_name
_, stderr_str, status = Open3.capture3(*lima_cmd)

unless status.success?
Expand All @@ -129,8 +131,10 @@ def stop(vm_name)
true
end

def delete(vm_names)
lima_cmd = [@limactl, 'delete'] + vm_names
def delete(vm_names, force = false)
lima_cmd = [@limactl, 'delete']
lima_cmd << '--force' if force
lima_cmd += vm_names
_, stderr_str, status = Open3.capture3(*lima_cmd)

unless status.success?
Expand Down
8 changes: 7 additions & 1 deletion plans/cluster/delete.pp
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
# @summary Delete the cluster of Lima VMs
# @param name
# Cluster name
# @param force
# Forcibly stop the processes
# @param clusters
# Hash of all defined clusters. Populated from Hiera usually.
# @param target
# The host to run the limactl on
plan lima::cluster::delete (
String[1] $name,
Boolean $force = false,
Optional[Hash] $clusters = undef,
TargetSpec $target = 'localhost',
) {
Expand All @@ -21,5 +24,8 @@
}
out::verbose("Nodes to delete: ${defined_nodes}")

return run_task('lima::delete', $target, 'names' => $defined_nodes)
return run_task('lima::delete', $target, {
'names' => $defined_nodes,
'force' => $force,
})
}
18 changes: 8 additions & 10 deletions plans/cluster/stop.pp
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
# @summary Stop the cluster of Lima VMs
# @param name
# Cluster name
# @param force
# Forcibly stop the processes
# @param clusters
# Hash of all defined clusters. Populated from Hiera usually.
# @param target
# The host to run the limactl on
plan lima::cluster::stop (
String[1] $name,
Boolean $force = false,
Optional[Hash] $clusters = undef,
TargetSpec $target = 'localhost',
) {
Expand All @@ -22,11 +25,7 @@
out::verbose("Defined nodes: ${defined_nodes}")

$list_res = without_default_logging() || {
run_task(
'lima::list',
$target,
'names' => $defined_nodes,
)
run_task('lima::list', $target, 'names' => $defined_nodes)
}
$running_nodes = $list_res.find($target).value['list']
.filter |$x| { $x['status'] == 'Running' }
Expand All @@ -35,11 +34,10 @@

# Stop running nodes
$stop_res = parallelize ($running_nodes) |$node| {
run_task(
'lima::stop',
$target,
'name' => $node,
)
run_task('lima::stop', $target, {
'name' => $node,
'force' => $force,
})
}

return $stop_res
Expand Down
50 changes: 38 additions & 12 deletions spec/lima/limactl_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -212,26 +212,52 @@ module Lima
describe '#stop' do
let(:vm_status) { 'Stopped' }

it 'stops the VM' do
allow(Open3).to receive(:capture3).with('limactl', 'stop', vm_name)
.and_return(['', '', lima_success])
context 'when force unset' do
it 'stops the VM' do
allow(Open3).to receive(:capture3).with('limactl', 'stop', vm_name)
.and_return(['', '', lima_success])

result = lima_helper.stop(vm_name)
expect(Open3).to have_received(:capture3).with('limactl', 'stop', vm_name).once
expect(result).to be(true)
end
end

context 'when force=true' do
it 'stops the VM in force mode' do
allow(Open3).to receive(:capture3).with('limactl', 'stop', '--force', vm_name)
.and_return(['', '', lima_success])

result = lima_helper.stop(vm_name)
expect(Open3).to have_received(:capture3).with('limactl', 'stop', vm_name).once
expect(result).to be(true)
result = lima_helper.stop(vm_name, true)
expect(Open3).to have_received(:capture3).with('limactl', 'stop', '--force', vm_name).once
expect(result).to be(true)
end
end
end

describe '#delete' do
let(:vms) { ['test', 'example'] }

it 'deletes the VM' do
allow(Open3).to receive(:capture3).with('limactl', 'delete', *vms)
.and_return(['', '', lima_success])
context 'when force unset' do
it 'deletes the VMs' do
allow(Open3).to receive(:capture3).with('limactl', 'delete', *vms)
.and_return(['', '', lima_success])

result = lima_helper.delete(vms)
expect(Open3).to have_received(:capture3).with('limactl', 'delete', *vms).once
expect(result).to be(true)
result = lima_helper.delete(vms)
expect(Open3).to have_received(:capture3).with('limactl', 'delete', *vms).once
expect(result).to be(true)
end
end

context 'when force=true' do
it 'deletes the VMs in force mode' do
allow(Open3).to receive(:capture3).with('limactl', 'delete', '--force', *vms)
.and_return(['', '', lima_success])

result = lima_helper.delete(vms, true)
expect(Open3).to have_received(:capture3).with('limactl', 'delete', '--force', *vms).once
expect(result).to be(true)
end
end
end

Expand Down
55 changes: 39 additions & 16 deletions spec/plans/cluster/delete_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
require 'spec_helper'

describe 'lima::cluster::delete' do
let(:plan) { subject }
let(:cluster_name) { 'example' }
let(:plan) { 'lima::cluster::delete' }
let(:nodes) do
[
'example-main',
Expand All @@ -15,8 +14,8 @@
end
let(:clusters) do
{
cluster_name => {
'nodes' => [
'example' => {
'nodes' => [
nodes[0],
nodes[1],
{
Expand All @@ -29,26 +28,50 @@
},
}
end
let(:cluster_name) { 'example' }
let(:cluster) { clusters[cluster_name] }
let(:plan_params) { { 'name' => cluster_name, 'clusters' => clusters } }
let(:force) { false }

it 'fails when wrong name specified' do
result = run_plan(plan, { 'name' => 'nonexistent', 'clusters' => clusters })
context 'with non-existent cluster' do
let(:cluster_name) { 'nonexistent' }

expect(result.ok?).to be(false)
expect(result.value.msg).to match(%r{Cluster 'nonexistent' is not defined})
it 'fails' do
result = run_plan(plan, plan_params)

expect(result.ok?).to be(false)
expect(result.value.msg).to match(%r{Cluster 'nonexistent' is not defined})
end
end

it 'deletes all nodes in the cluster' do
expect_plan('lima::clusters').always_return(cluster)
context 'with existing cluster' do
before :each do
expect_plan('lima::clusters').always_return(cluster)
expect_task('lima::delete').be_called_times(1).with_params('names' => nodes, 'force' => force).always_return(delete: true)
expect_out_verbose.with_params("Nodes to delete: [#{nodes.join(', ')}]")
end

context 'with force unset' do
it 'deletes all nodes in the cluster' do
result = run_plan(plan, plan_params)

expect_task('lima::delete').be_called_times(1).with_params('names' => nodes).always_return(delete: true)
expect(result.ok?).to be(true)
expect(result.value.count).to eq(1)
expect(result.value[0].value).to eq('delete' => true)
end
end

expect_out_verbose.with_params("Nodes to delete: [#{nodes.join(', ')}]")
context 'with force => true' do
let(:force) { true }
let(:plan_params) { super().merge('force' => force) }

result = run_plan(plan, { 'name' => cluster_name, 'clusters' => clusters })
it 'deletes all nodes in the cluster' do
result = run_plan(plan, plan_params)

expect(result.ok?).to be(true)
expect(result.value.count).to eq(1)
expect(result.value[0].value).to eq('delete' => true)
expect(result.ok?).to be(true)
expect(result.value.count).to eq(1)
expect(result.value[0].value).to eq('delete' => true)
end
end
end
end
70 changes: 46 additions & 24 deletions spec/plans/cluster/stop_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
require 'spec_helper'

describe 'lima::cluster::stop' do
let(:plan) { subject }
let(:cluster_name) { 'example' }
let(:plan) { 'lima::cluster::stop' }
let(:nodes) do
[
'example-main',
Expand All @@ -15,8 +14,8 @@
end
let(:clusters) do
{
cluster_name => {
'nodes' => [
'example' => {
'nodes' => [
nodes[0],
nodes[1],
{
Expand All @@ -29,6 +28,7 @@
},
}
end
let(:cluster_name) { 'example' }
let(:cluster) { clusters[cluster_name] }
let(:lima_list_res) do
{
Expand All @@ -39,35 +39,57 @@
]
}
end
let(:nodes_to_stop) { lima_list_res[:list].filter { |x| x[:status] == 'Running' }.map { |x| x[:name] } }
let(:plan_params) { { 'name' => cluster_name, 'clusters' => clusters } }
let(:force) { false }

it 'fails when wrong name specified' do
result = run_plan(plan, 'name' => 'nonexistent', 'clusters' => clusters)
context 'with non-existent cluster' do
let(:cluster_name) { 'nonexistent' }

expect(result.ok?).to be(false)
expect(result.value.msg).to match(%r{Cluster 'nonexistent' is not defined})
it 'fails' do
result = run_plan(plan, plan_params)

expect(result.ok?).to be(false)
expect(result.value.msg).to match(%r{Cluster 'nonexistent' is not defined})
end
end

it 'stops all non-running nodes in the cluster' do
expect_plan('lima::clusters').always_return(cluster)
expect_task('lima::list').be_called_times(1).always_return(lima_list_res)
context 'with existing cluster' do
before :each do
expect_plan('lima::clusters').always_return(cluster)
expect_task('lima::list').be_called_times(1).always_return(lima_list_res)
nodes_to_stop.each do |node|
expect_task('lima::stop').be_called_times(1).with_params('name' => node, 'force' => force).always_return(stop: true)
end
expect_out_verbose.with_params("Defined nodes: [#{nodes.join(', ')}]")
expect_out_verbose.with_params("Nodes to stop: [#{nodes_to_stop.join(', ')}]")
end

nodes_to_stop = [
nodes[0],
nodes[2],
]
nodes_to_stop.each do |node|
expect_task('lima::stop').be_called_times(1).with_params('name' => node).always_return(stop: true)
context 'with force unset' do
it 'stops all non-running nodes in the cluster' do
result = run_plan(plan, plan_params)

expect(result.ok?).to be(true)
expect(result.value.count).to eq(nodes_to_stop.length)
result.value.each do |r|
expect(r.first.value).to eq('stop' => true)
end
end
end

expect_out_verbose.with_params("Defined nodes: [#{nodes.join(', ')}]")
expect_out_verbose.with_params("Nodes to stop: [#{nodes_to_stop.join(', ')}]")
context 'with force => true' do
let(:force) { true }
let(:plan_params) { super().merge('force' => force) }

result = run_plan(plan, 'name' => cluster_name, 'clusters' => clusters)
it 'stops all non-running nodes in the cluster' do
result = run_plan(plan, plan_params)

expect(result.ok?).to be(true)
expect(result.value.count).to eq(nodes_to_stop.length)
result.value.each do |r|
expect(r.first.value).to eq('stop' => true)
expect(result.ok?).to be(true)
expect(result.value.count).to eq(nodes_to_stop.length)
result.value.each do |r|
expect(r.first.value).to eq('stop' => true)
end
end
end
end
end
Loading

0 comments on commit 04d01c8

Please sign in to comment.