Skip to content

Commit

Permalink
Volume Start and Stop
Browse files Browse the repository at this point in the history
Signed-off-by: Aravinda Vishwanathapura <[email protected]>
  • Loading branch information
aravindavk committed Dec 7, 2021
1 parent e4644aa commit 3139736
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 11 deletions.
19 changes: 19 additions & 0 deletions clients/crystal/src/volumes.cr
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,24 @@ module MoanaClient
MoanaClient.error_response(response)
end
end

def start_stop_volume(action)
url = "#{@client.url}/api/v1/pools/#{@pool_name}/volumes/#{@name}/#{action}"

response = MoanaClient.http_post(url, "{}", headers: @client.auth_header)
if response.status_code == 200
MoanaTypes::Volume.from_json(response.body)
else
MoanaClient.error_response(response)
end
end

def start
start_stop_volume("start")
end

def stop
start_stop_volume("stop")
end
end
end
36 changes: 36 additions & 0 deletions mgr/src/cmds/volumes.cr
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,42 @@ handler "volume.create" do |args|
end
end

command "volume.start", "Start the Kadalu Storage Volume" do |parser, _|
parser.banner = "Usage: kadalu volume start POOL/VOLNAME [arguments]"
end

handler "volume.start" do |args|
begin
args.pool_name, volume_name = pool_and_volume_name(args.pos_args.size > 0 ? args.pos_args[0] : "")
api_call(args, "Failed to Start the Volume") do |client|
volume = client.pool(args.pool_name).volume(volume_name).start
puts "Volume #{volume.name} started successfully"
end
rescue ex : InvalidVolumeRequest
STDERR.puts "Volume start failed"
STDERR.puts ex
exit 1
end
end

command "volume.stop", "Stop the Kadalu Storage Volume" do |parser, _|
parser.banner = "Usage: kadalu volume stop POOL/VOLNAME [arguments]"
end

handler "volume.stop" do |args|
begin
args.pool_name, volume_name = pool_and_volume_name(args.pos_args.size > 0 ? args.pos_args[0] : "")
api_call(args, "Failed to Stop the Volume") do |client|
volume = client.pool(args.pool_name).volume(volume_name).stop
puts "Volume #{volume.name} stopped successfully"
end
rescue ex : InvalidVolumeRequest
STDERR.puts "Volume stop failed"
STDERR.puts ex
exit 1
end
end

command "volume.list", "Volumes list of a Kadalu Storage Pool" do |parser, args|
parser.banner = "Usage: kadalu volume list POOL [arguments]"
parser.on("--status", "Show Volumes states") do
Expand Down
2 changes: 1 addition & 1 deletion mgr/src/server/datastore/services.cr
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module Datastore
end

def self.disable_service(pool_name, node_name, service)
File.remove(service_file(pool_name, node_name, service.id))
File.delete(service_file(pool_name, node_name, service.id))
end

def self.list_services(pool_name, node_name)
Expand Down
16 changes: 8 additions & 8 deletions mgr/src/server/datastore/volumes.cr
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,6 @@ module Datastore
Path.new(volume_dir(pool_name, volume_name), "info")
end

def self.save_volume(pool_name, volume)
Dir.mkdir_p(volume_dir(pool_name, volume.name))
File.write(volume_file(pool_name, volume.name), volume.to_json)

volume
end

def self.list_volumes(pool_name)
volumes = [] of MoanaTypes::Volume
volumes_dir = Path.new(@@rootdir, "pools", pool_name, "volumes")
Expand All @@ -44,13 +37,20 @@ module Datastore
vol = get_volume(pool_name, volume.name)
raise DatastoreError.new("Volume already exists") unless vol.nil?

update_volume(pool_name, volume)
end

def self.update_volume(pool_name, volume)
volume.distribute_groups.each do |dist_grp|
dist_grp.storage_units.each do |storage_unit|
# Do not store the redundant node information.
# node_name is already available.
storage_unit.node = MoanaTypes::Node.new
end
end
save_volume(pool_name, volume)
Dir.mkdir_p(volume_dir(pool_name, volume.name))
File.write(volume_file(pool_name, volume.name), volume.to_json)

volume
end
end
2 changes: 0 additions & 2 deletions mgr/src/server/plugins/volume_create.cr
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ node_action ACTION_VALIDATE_VOLUME_CREATE do |data|
validate_volume_create(req)
end

alias VolumeRequestToNode = Tuple(Hash(String, Array(MoanaTypes::ServiceUnit)), Hash(String, Array(MoanaTypes::Volfile)), MoanaTypes::Volume)

node_action ACTION_VOLUME_CREATE do |data|
handle_volume_create(data, stopped: false)
end
Expand Down
79 changes: 79 additions & 0 deletions mgr/src/server/plugins/volume_start_stop.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
require "moana_types"

require "../conf"
require "./helpers"
require "../datastore/*"
require "./ping"
require "./volume_utils.cr"

ACTION_VOLUME_START = "volume_start"
ACTION_VOLUME_STOP = "volume_stop"

node_action ACTION_VOLUME_START do |data|
handle_node_volume_start_stop(data, "start")
end

node_action ACTION_VOLUME_STOP do |data|
handle_node_volume_start_stop(data, "stop")
end

def volume_start_stop(env, action)
pool_name = env.params.url["pool_name"]
volume_name = env.params.url["volume_name"]

volume = Datastore.get_volume(pool_name, volume_name)

if volume.nil?
env.response.status_code = 400
return {"error": "Volume doesn't exists"}.to_json
end

return volume.to_json if action == "start" && volume.state == "Started"
return volume.to_json if action == "stop" && volume.state == "Stopped"

nodes = participating_nodes(pool_name, volume)
node_details_add_to_volume(volume, nodes)

# TODO: Add to missed_ops if a node is not reachable

# Generate Services and Volfiles if Volume to be started
services, volfiles = services_and_volfiles(volume)

resp = dispatch_action(
action == "start" ? ACTION_VOLUME_START : ACTION_VOLUME_STOP,
pool_name,
nodes,
{services, volfiles, volume}.to_json
)

if !resp.ok
env.response.status_code = 400
return node_errors("Failed to #{action} the Volume", resp.node_responses).to_json
end

# Save Services details
services.each do |node, svcs|
svcs.each do |svc|
if action == "start"
# Enable each Services
Datastore.enable_service(pool_name, node, svc)
else
# Disable each Services
Datastore.disable_service(pool_name, node, svc)
end
end
end

volume.state = action == "start" ? "Started" : "Stopped"
Datastore.update_volume(pool_name, volume)

volume.to_json
end

post "/api/v1/pools/:pool_name/volumes/:volume_name/start" do |env|
volume_start_stop(env, "start")
end

post "/api/v1/pools/:pool_name/volumes/:volume_name/stop" do |env|
volume_start_stop(env, "stop")
end
28 changes: 28 additions & 0 deletions mgr/src/server/plugins/volume_utils.cr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require "../datastore/*"
require "../default_volfiles"

VOLUME_ID_XATTR_NAME = "trusted.glusterfs.volume-id"
alias VolumeRequestToNode = Tuple(Hash(String, Array(MoanaTypes::ServiceUnit)), Hash(String, Array(MoanaTypes::Volfile)), MoanaTypes::Volume)

def volfile_get(name)
# TODO: Add logic to read from the Templates directory
Expand Down Expand Up @@ -79,6 +80,33 @@ def validate_volume_create(req)
NodeResponse.new(true, "")
end

def handle_node_volume_start_stop(data, action)
services, volfiles, _ = VolumeRequestToNode.from_json(data)

if action == "start" && !volfiles[GlobalConfig.local_node.name]?.nil?
Dir.mkdir_p(Path.new(GlobalConfig.workdir, "volfiles"))
volfiles[GlobalConfig.local_node.name].each do |volfile|
File.write(Path.new(GlobalConfig.workdir, "volfiles", "#{volfile.name}.vol"), volfile.content)
end
end

unless services[GlobalConfig.local_node.name]?.nil?
# TODO: Hard coded path change?
Dir.mkdir_p("/var/log/kadalu")
Dir.mkdir_p("/var/run/kadalu")
services[GlobalConfig.local_node.name].each do |service|
svc = Service.from_json(service.to_json)
if action == "start"
svc.start
else
svc.stop
end
end
end

NodeResponse.new(true, "")
end

def handle_volume_create(data, stopped = false)
services, volfiles, req = VolumeRequestToNode.from_json(data)
resp = Hash(String, MoanaTypes::StorageUnit).new
Expand Down

0 comments on commit 3139736

Please sign in to comment.