235 lines
6.9 KiB
Python
Executable File
235 lines
6.9 KiB
Python
Executable File
#!/usr/bin/python3
|
|
# Copyright 2017 Canonical Ltd
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
import os
|
|
import sys
|
|
|
|
sys.path.append('lib')
|
|
|
|
from charmhelpers.core import hookenv
|
|
from charmhelpers.core.hookenv import action_get, action_fail, action_set
|
|
from gluster.cli import GlusterCmdException
|
|
from charm.gluster import volume
|
|
|
|
|
|
def rebalance_volume():
|
|
"""
|
|
Start a rebalance volume operation
|
|
"""
|
|
vol = action_get("volume")
|
|
if not vol:
|
|
action_fail("volume not specified")
|
|
try:
|
|
volume.volume_rebalance(vol)
|
|
except GlusterCmdException as e:
|
|
action_fail("volume rebalance failed with error: {}".format(e))
|
|
|
|
|
|
def enable_bitrot_scan():
|
|
"""
|
|
Enable bitrot scan
|
|
"""
|
|
vol = action_get("volume")
|
|
if not vol:
|
|
action_fail("volume not specified")
|
|
try:
|
|
volume.volume_enable_bitrot(vol)
|
|
except GlusterCmdException as e:
|
|
action_fail("enable bitrot failed with error: {}".format(e))
|
|
|
|
|
|
def disable_bitrot_scan():
|
|
"""
|
|
Disable bitrot scan
|
|
"""
|
|
vol = action_get("volume")
|
|
if not vol:
|
|
action_fail("volume not specified")
|
|
try:
|
|
volume.volume_disable_bitrot(vol)
|
|
except GlusterCmdException as e:
|
|
action_fail("enable disable failed with error: {}".format(e))
|
|
|
|
|
|
def pause_bitrot_scan():
|
|
"""
|
|
Pause bitrot scan
|
|
"""
|
|
vol = action_get("volume")
|
|
option = volume.BitrotOption.Scrub(volume.ScrubControl.Pause)
|
|
try:
|
|
volume.volume_set_bitrot_option(vol, option)
|
|
except GlusterCmdException as e:
|
|
action_fail("pause bitrot scan failed with error: {}".format(e))
|
|
|
|
|
|
def resume_bitrot_scan():
|
|
"""
|
|
Resume bitrot scan
|
|
"""
|
|
vol = action_get("volume")
|
|
option = volume.BitrotOption.Scrub(volume.ScrubControl.Resume)
|
|
try:
|
|
volume.volume_set_bitrot_option(vol, option)
|
|
except GlusterCmdException as e:
|
|
action_fail("resume bitrot scan failed with error: {}".format(e))
|
|
|
|
|
|
def set_bitrot_scan_frequency():
|
|
"""
|
|
Set the bitrot scan frequency
|
|
"""
|
|
vol = action_get("volume")
|
|
frequency = action_get("frequency")
|
|
option = volume.ScrubSchedule.from_str(frequency)
|
|
try:
|
|
volume.volume_set_bitrot_option(vol,
|
|
volume.BitrotOption.ScrubFrequency(
|
|
option))
|
|
except GlusterCmdException as e:
|
|
action_fail("set bitrot scan frequency failed with error: {}".format(
|
|
e))
|
|
|
|
|
|
def set_bitrot_throttle():
|
|
"""
|
|
Set how aggressive bitrot scanning should be
|
|
"""
|
|
vol = action_get("volume")
|
|
throttle = action_get("throttle")
|
|
option = volume.ScrubAggression.from_str(throttle)
|
|
try:
|
|
volume.volume_set_bitrot_option(vol, volume.BitrotOption.ScrubThrottle(
|
|
option))
|
|
except GlusterCmdException as e:
|
|
action_fail(
|
|
"set bitrot throttle failed with error: {}".format(e))
|
|
|
|
|
|
def enable_volume_quota():
|
|
"""
|
|
Enable quotas on the volume
|
|
"""
|
|
# Gather our action parameters
|
|
vol = action_get("volume")
|
|
usage_limit = action_get("usage-limit")
|
|
parsed_usage_limit = int(usage_limit)
|
|
path = action_get("path")
|
|
# Turn quotas on if not already enabled
|
|
quotas_enabled = volume.volume_quotas_enabled(vol)
|
|
if quotas_enabled.is_err():
|
|
action_fail("Enable quota failed: {}".format(quotas_enabled.value))
|
|
if not quotas_enabled.value:
|
|
try:
|
|
volume.volume_enable_quotas(vol)
|
|
except GlusterCmdException as e:
|
|
action_fail("Enable quotas failed: {}".format(e))
|
|
|
|
try:
|
|
volume.volume_add_quota(vol, path, parsed_usage_limit)
|
|
except GlusterCmdException as e:
|
|
action_fail("Add quota failed: {}".format(e))
|
|
|
|
|
|
def disable_volume_quota():
|
|
"""
|
|
Disable quotas on the volume
|
|
"""
|
|
vol = action_get("volume")
|
|
path = action_get("path")
|
|
quotas_enabled = volume.volume_quotas_enabled(vol)
|
|
if quotas_enabled.is_err():
|
|
action_fail("Disable quota failed: {}".format(quotas_enabled.value))
|
|
if quotas_enabled.value:
|
|
try:
|
|
volume.volume_remove_quota(vol, path)
|
|
except GlusterCmdException as e:
|
|
action_fail("remove quota failed with error: {}".format(e))
|
|
|
|
|
|
def list_volume_quotas():
|
|
"""
|
|
List quotas on the volume
|
|
"""
|
|
vol = action_get("volume")
|
|
quotas_enabled = volume.volume_quotas_enabled(vol)
|
|
if quotas_enabled.is_err():
|
|
action_fail("List quota failed: {}".format(quotas_enabled.value))
|
|
if quotas_enabled.value:
|
|
quotas = volume.quota_list(vol)
|
|
if quotas.is_err():
|
|
action_fail(
|
|
"Failed to get volume quotas: {}".format(quotas.value))
|
|
quota_strings = []
|
|
for quota in quotas.value:
|
|
quota_string = "path:{} limit:{} used:{}".format(
|
|
quota.path,
|
|
quota.hard_limit,
|
|
quota.used)
|
|
quota_strings.append(quota_string)
|
|
action_set({"quotas": "\n".join(quota_strings)})
|
|
|
|
|
|
def set_volume_options():
|
|
"""
|
|
Set one or more options on the volume at once
|
|
"""
|
|
vol = action_get("volume")
|
|
|
|
# Gather all of the action parameters up at once. We don't know what
|
|
# the user wants to change.
|
|
options = action_get()
|
|
settings = []
|
|
for key in options:
|
|
if key != "volume":
|
|
settings.append(
|
|
volume.GlusterOption.from_str(key, options[key]))
|
|
|
|
volume.volume_set_options(vol, settings)
|
|
|
|
|
|
# Actions to function mapping, to allow for illegal python action names that
|
|
# can map to a python function.
|
|
ACTIONS = {
|
|
"create-volume-quota": enable_volume_quota,
|
|
"delete-volume-quota": disable_volume_quota,
|
|
"disable-bitrot-scan": disable_bitrot_scan,
|
|
"enable-bitrot-scan": enable_bitrot_scan,
|
|
"list-volume-quotas": list_volume_quotas,
|
|
"pause-bitrot-scan": pause_bitrot_scan,
|
|
"rebalance-volume": rebalance_volume,
|
|
"resume-bitrot-scan": resume_bitrot_scan,
|
|
"set-bitrot-scan-frequency": set_bitrot_scan_frequency,
|
|
"set-bitrot-throttle": set_bitrot_throttle,
|
|
"set-volume-options": set_volume_options,
|
|
}
|
|
|
|
|
|
def main(args):
|
|
action_name = os.path.basename(args[0])
|
|
try:
|
|
action = ACTIONS[action_name]
|
|
except KeyError:
|
|
return "Action %s undefined" % action_name
|
|
else:
|
|
try:
|
|
action()
|
|
except Exception as e:
|
|
hookenv.action_fail(str(e))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main(sys.argv))
|