summaryrefslogtreecommitdiffstats
path: root/extras/snap_scheduler/snap_scheduler.py
diff options
context:
space:
mode:
Diffstat (limited to 'extras/snap_scheduler/snap_scheduler.py')
-rwxr-xr-xextras/snap_scheduler/snap_scheduler.py197
1 files changed, 147 insertions, 50 deletions
diff --git a/extras/snap_scheduler/snap_scheduler.py b/extras/snap_scheduler/snap_scheduler.py
index b426cc7bb73..e8fcc449a9b 100755
--- a/extras/snap_scheduler/snap_scheduler.py
+++ b/extras/snap_scheduler/snap_scheduler.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
#
# Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com>
# This file is part of GlusterFS.
@@ -67,7 +67,7 @@ except ImportError:
SCRIPT_NAME = "snap_scheduler"
scheduler_enabled = False
log = logging.getLogger(SCRIPT_NAME)
-SHARED_STORAGE_DIR="/var/run/gluster/shared_storage"
+SHARED_STORAGE_DIR="/run/gluster/shared_storage"
GCRON_DISABLED = SHARED_STORAGE_DIR+"/snaps/gcron_disabled"
GCRON_ENABLED = SHARED_STORAGE_DIR+"/snaps/gcron_enabled"
GCRON_TASKS = SHARED_STORAGE_DIR+"/snaps/glusterfs_snap_cron_tasks"
@@ -149,7 +149,7 @@ def initLogger():
sh.setFormatter(formatter)
process = subprocess.Popen(["gluster", "--print-logdir"],
- stdout=subprocess.PIPE)
+ stdout=subprocess.PIPE, universal_newlines=True)
logfile = os.path.join(process.stdout.read()[:-1], SCRIPT_NAME + ".log")
fh = logging.FileHandler(logfile)
@@ -207,11 +207,11 @@ def enable_scheduler():
os.remove(GCRON_TASKS)
try:
f = os.open(GCRON_ENABLED, os.O_CREAT | os.O_NONBLOCK,
- 0644)
+ 0o644)
os.close(f)
- except OSError as (errno, strerror):
+ except OSError as e:
log.error("Failed to open %s. Error: %s.",
- GCRON_ENABLED, strerror)
+ GCRON_ENABLED, e)
ret = INTERNAL_ERROR
return ret
os.symlink(GCRON_ENABLED, GCRON_TASKS)
@@ -219,8 +219,9 @@ def enable_scheduler():
log.info("Snapshot scheduling is enabled")
output("Snapshot scheduling is enabled")
ret = 0
- except OSError as (errno, strerror):
- print_str = "Failed to enable snapshot scheduling. Error: "+strerror
+ except OSError as e:
+ print_str = ("Failed to enable snapshot scheduling."
+ "Error: {{}}" + e)
log.error(print_str)
output(print_str)
ret = INTERNAL_ERROR
@@ -262,14 +263,15 @@ def disable_scheduler():
os.remove(GCRON_DISABLED)
if os.path.lexists(GCRON_TASKS):
os.remove(GCRON_TASKS)
- f = os.open(GCRON_DISABLED, os.O_CREAT, 0644)
+ f = os.open(GCRON_DISABLED, os.O_CREAT, 0o644)
os.close(f)
os.symlink(GCRON_DISABLED, GCRON_TASKS)
log.info("Snapshot scheduling is disabled")
output("Snapshot scheduling is disabled")
ret = 0
- except OSError as (errno, strerror):
- print_str = "Failed to disable snapshot scheduling. Error: "+strerror
+ except OSError as e:
+ print_str = ("Failed to disable snapshot scheduling. Error: "
+ + e)
log.error(print_str)
output(print_str)
ret = INTERNAL_ERROR
@@ -308,8 +310,8 @@ def load_tasks_from_file():
tasks[jobname] = schedule+":"+volname
f.close()
ret = 0
- except IOError as (errno, strerror):
- log.error("Failed to open %s. Error: %s.", GCRON_ENABLED, strerror)
+ except IOError as e:
+ log.error("Failed to open %s. Error: %s.", GCRON_ENABLED, e)
ret = INTERNAL_ERROR
return ret
@@ -322,8 +324,8 @@ def get_current_scheduler():
current_scheduler = f.readline().rstrip('\n')
f.close()
ret = 0
- except IOError as (errno, strerror):
- log.error("Failed to open %s. Error: %s.", CURRENT_SCHEDULER, strerror)
+ except IOError as e:
+ log.error("Failed to open %s. Error: %s.", CURRENT_SCHEDULER, e)
ret = INTERNAL_ERROR
return ret
@@ -363,7 +365,7 @@ def list_schedules():
def write_tasks_to_file():
try:
- with open(TMP_FILE, "w", 0644) as f:
+ with open(TMP_FILE, "w", 0o644) as f:
# If tasks is empty, just create an empty tmp file
if len(tasks) != 0:
for key in sorted(tasks):
@@ -376,8 +378,8 @@ def write_tasks_to_file():
f.flush()
os.fsync(f.fileno())
f.close()
- except IOError as (errno, strerror):
- log.error("Failed to open %s. Error: %s.", TMP_FILE, strerror)
+ except IOError as e:
+ log.error("Failed to open %s. Error: %s.", TMP_FILE, e)
ret = INTERNAL_ERROR
return ret
@@ -388,13 +390,13 @@ def write_tasks_to_file():
def update_current_scheduler(data):
try:
- with open(TMP_FILE, "w", 0644) as f:
+ with open(TMP_FILE, "w", 0o644) as f:
f.write("%s" % data)
f.flush()
os.fsync(f.fileno())
f.close()
- except IOError as (errno, strerror):
- log.error("Failed to open %s. Error: %s.", TMP_FILE, strerror)
+ except IOError as e:
+ log.error("Failed to open %s. Error: %s.", TMP_FILE, e)
ret = INTERNAL_ERROR
return ret
@@ -457,11 +459,11 @@ def add_schedules(jobname, schedule, volname):
job_lockfile = LOCK_FILE_DIR + jobname
try:
f = os.open(job_lockfile, os.O_CREAT | os.O_NONBLOCK,
- 0644)
+ 0o644)
os.close(f)
- except OSError as (errno, strerror):
+ except OSError as e:
log.error("Failed to open %s. Error: %s.",
- job_lockfile, strerror)
+ job_lockfile, e)
ret = INTERNAL_ERROR
return ret
log.info("Successfully added snapshot schedule %s" %
@@ -489,9 +491,9 @@ def delete_schedules(jobname):
job_lockfile = LOCK_FILE_DIR+jobname
try:
os.remove(job_lockfile)
- except OSError as (errno, strerror):
+ except OSError as e:
log.error("Failed to open %s. Error: %s.",
- job_lockfile, strerror)
+ job_lockfile, e)
ret = INTERNAL_ERROR
return ret
log.info("Successfully deleted snapshot schedule %s"
@@ -545,18 +547,113 @@ def edit_schedules(jobname, schedule, volname):
return ret
+def get_bool_val():
+ getsebool_cli = ["getsebool",
+ "-a"]
+ p1 = subprocess.Popen(getsebool_cli, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+
+ grep_cmd = ["grep",
+ "cron_system_cronjob_use_shares"]
+ p2 = subprocess.Popen(grep_cmd, stdin=p1.stdout,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+
+ p1.stdout.close()
+ output, err = p2.communicate()
+ rv = p2.returncode
+
+ if rv:
+ log.error("Command output:")
+ log.error(err)
+ return -1
+
+ bool_val = output.split()[2]
+ log.debug("Bool value = '%s'", bool_val)
+
+ return bool_val
+
+def get_selinux_status():
+ getenforce_cli = ["getenforce"]
+ log.debug("Running command '%s'", " ".join(getenforce_cli))
+
+ try:
+ p1 = subprocess.Popen(getenforce_cli, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ except OSError as oserr:
+ log.error("Failed to run the command \"getenforce\". Error: %s" %\
+ oserr)
+ return -1
+
+ output, err = p1.communicate()
+ rv = p1.returncode
+
+ if rv:
+ log.error("Command output:")
+ log.error(err)
+ return -1
+ else:
+ selinux_status=output.rstrip()
+ log.debug("selinux status: %s", selinux_status)
+
+ return selinux_status
+
+def set_cronjob_user_share():
+ selinux_status = get_selinux_status()
+ if (selinux_status == -1):
+ log.error("Failed to get selinux status")
+ return -1
+ elif (selinux_status == "Disabled"):
+ return 0
+
+ bool_val = get_bool_val()
+ # In case of a failure (where the boolean value is not)
+ # present in the system, we should not proceed further
+ # We should only proceed when the value is "off"
+ if (bool_val == -1 or bool_val != "off"):
+ return 0
+
+ setsebool_cli = ["setsebool", "-P",
+ "cron_system_cronjob_use_shares",
+ "on"]
+ log.debug("Running command '%s'", " ".join(setsebool_cli))
+
+ p1 = subprocess.Popen(setsebool_cli, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+
+ output, err = p1.communicate()
+ rv = p1.returncode
+
+ if rv:
+ log.error("Command output:")
+ log.error(err)
+ return rv
+
+ bool_val = get_bool_val()
+ if (bool_val == "on"):
+ return 0
+ else:
+ # In case of an error or if boolean is not on
+ # we return a failure here
+ return -1
def initialise_scheduler():
+ ret = set_cronjob_user_share()
+ if ret:
+ log.error("Failed to set selinux boolean "
+ "cron_system_cronjob_use_shares to 'on'")
+ return ret
+
try:
- with open(TMP_FILE, "w+", 0644) as f:
+ with open(TMP_FILE, "w+", 0o644) as f:
updater = ("* * * * * root PATH=$PATH:/usr/local/sbin:"
"/usr/sbin gcron.py --update\n")
f.write("%s\n" % updater)
f.flush()
os.fsync(f.fileno())
f.close()
- except IOError as (errno, strerror):
- log.error("Failed to open %s. Error: %s.", TMP_FILE, strerror)
+ except IOError as e:
+ log.error("Failed to open %s. Error: %s.", TMP_FILE, e)
ret = INIT_FAILED
return ret
@@ -564,10 +661,10 @@ def initialise_scheduler():
if not os.path.lexists(GCRON_TASKS):
try:
- f = open(GCRON_TASKS, "w", 0644)
+ f = open(GCRON_TASKS, "w", 0o644)
f.close()
- except IOError as (errno, strerror):
- log.error("Failed to open %s. Error: %s.", GCRON_TASKS, strerror)
+ except IOError as e:
+ log.error("Failed to open %s. Error: %s.", GCRON_TASKS, e)
ret = INIT_FAILED
return ret
@@ -635,7 +732,7 @@ def perform_operation(args):
if ret == 0:
subprocess.Popen(["touch", "-h", GCRON_TASKS])
gf_event (EVENT_SNAPSHOT_SCHEDULER_DISABLED,
- status="Successfuly Disabled")
+ status="Successfully Disabled")
else:
gf_event (EVENT_SNAPSHOT_SCHEDULER_DISABLE_FAILED,
error=print_error(ret))
@@ -670,7 +767,7 @@ def perform_operation(args):
if ret == 0:
subprocess.Popen(["touch", "-h", GCRON_TASKS])
gf_event (EVENT_SNAPSHOT_SCHEDULER_ENABLED,
- status="Successfuly Enabled")
+ status="Successfully Enabled")
else:
gf_event (EVENT_SNAPSHOT_SCHEDULER_ENABLE_FAILED,
error=print_error(ret))
@@ -682,7 +779,7 @@ def perform_operation(args):
if ret == 0:
subprocess.Popen(["touch", "-h", GCRON_TASKS])
gf_event (EVENT_SNAPSHOT_SCHEDULER_DISABLED,
- status="Successfuly Disabled")
+ status="Successfully Disabled")
else:
gf_event (EVENT_SNAPSHOT_SCHEDULER_DISABLE_FAILED,
error=print_error(ret))
@@ -702,7 +799,7 @@ def perform_operation(args):
if ret == 0:
subprocess.Popen(["touch", "-h", GCRON_TASKS])
gf_event (EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_ADDED,
- status="Successfuly added job "+args.jobname)
+ status="Successfully added job "+args.jobname)
else:
gf_event (EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_ADD_FAILED,
status="Failed to add job "+args.jobname,
@@ -718,7 +815,7 @@ def perform_operation(args):
if ret == 0:
subprocess.Popen(["touch", "-h", GCRON_TASKS])
gf_event (EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_DELETED,
- status="Successfuly deleted job "+args.jobname)
+ status="Successfully deleted job "+args.jobname)
else:
gf_event (EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_DELETE_FAILED,
status="Failed to delete job "+args.jobname,
@@ -734,7 +831,7 @@ def perform_operation(args):
if ret == 0:
subprocess.Popen(["touch", "-h", GCRON_TASKS])
gf_event (EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_EDITED,
- status="Successfuly edited job "+args.jobname)
+ status="Successfully edited job "+args.jobname)
else:
gf_event (EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_EDIT_FAILED,
status="Failed to edit job "+args.jobname,
@@ -799,42 +896,42 @@ def main(argv):
if not os.path.exists(SHARED_STORAGE_DIR+"/snaps/"):
try:
os.makedirs(SHARED_STORAGE_DIR+"/snaps/")
- except OSError as (errno, strerror):
+ except OSError as e:
if errno != EEXIST:
- log.error("Failed to create %s : %s", SHARED_STORAGE_DIR+"/snaps/", strerror)
+ log.error("Failed to create %s : %s", SHARED_STORAGE_DIR+"/snaps/", e)
output("Failed to create %s. Error: %s"
- % (SHARED_STORAGE_DIR+"/snaps/", strerror))
+ % (SHARED_STORAGE_DIR+"/snaps/", e))
return INTERNAL_ERROR
if not os.path.exists(GCRON_ENABLED):
- f = os.open(GCRON_ENABLED, os.O_CREAT | os.O_NONBLOCK, 0644)
+ f = os.open(GCRON_ENABLED, os.O_CREAT | os.O_NONBLOCK, 0o644)
os.close(f)
if not os.path.exists(LOCK_FILE_DIR):
try:
os.makedirs(LOCK_FILE_DIR)
- except OSError as (errno, strerror):
+ except OSError as e:
if errno != EEXIST:
- log.error("Failed to create %s : %s", LOCK_FILE_DIR, strerror)
+ log.error("Failed to create %s : %s", LOCK_FILE_DIR, e)
output("Failed to create %s. Error: %s"
- % (LOCK_FILE_DIR, strerror))
+ % (LOCK_FILE_DIR, e))
return INTERNAL_ERROR
try:
- f = os.open(LOCK_FILE, os.O_CREAT | os.O_RDWR | os.O_NONBLOCK, 0644)
+ f = os.open(LOCK_FILE, os.O_CREAT | os.O_RDWR | os.O_NONBLOCK, 0o644)
try:
fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
ret = perform_operation(args)
fcntl.flock(f, fcntl.LOCK_UN)
- except IOError as (errno, strerror):
+ except IOError:
log.info("%s is being processed by another agent.", LOCK_FILE)
output("Another snap_scheduler command is running. "
"Please try again after some time.")
return ANOTHER_TRANSACTION_IN_PROGRESS
os.close(f)
- except OSError as (errno, strerror):
- log.error("Failed to open %s : %s", LOCK_FILE, strerror)
- output("Failed to open %s. Error: %s" % (LOCK_FILE, strerror))
+ except OSError as e:
+ log.error("Failed to open %s : %s", LOCK_FILE, e)
+ output("Failed to open %s. Error: %s" % (LOCK_FILE, e))
return INTERNAL_ERROR
return ret