From: Jan Fajerski Date: Wed, 13 May 2020 08:42:34 +0000 (+0200) Subject: pybind/mgr/snap-schedule: add interface to de-/activate schedules X-Git-Tag: v16.1.0~1299^2~17 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=759403a04fbc8dd067cc00cf94bddcb96d9422ed;p=ceph.git pybind/mgr/snap-schedule: add interface to de-/activate schedules This allows to 1) activate schedules that have previously been deactivated due to the path no existing and 2) allowing ussers to explicitly deactivate a schedule for debugging or maintenance purposes. Signed-off-by: Jan Fajerski --- diff --git a/src/pybind/mgr/snap_schedule/fs/schedule.py b/src/pybind/mgr/snap_schedule/fs/schedule.py index 4c91ffb4726a4..5c467de8c919a 100644 --- a/src/pybind/mgr/snap_schedule/fs/schedule.py +++ b/src/pybind/mgr/snap_schedule/fs/schedule.py @@ -157,7 +157,8 @@ class Schedule(object): INNER JOIN schedules_meta sm ON sm.schedule_id = s.id WHERE s.path = ? AND - strftime("%s", "now") - strftime("%s", sm.start) > 0 + strftime("%s", "now") - strftime("%s", sm.start) > 0 AND + s.active = 1 ORDER BY until;''' PROTO_GET_SCHEDULES = '''SELECT @@ -172,6 +173,7 @@ class Schedule(object): GET_SCHEDULE = PROTO_GET_SCHEDULES + ' s.path = ? and sm.start = ? AND sm.repeat = ?' + # TODO merge these two methods @classmethod def get_db_schedules(cls, path, db, fs): with db: @@ -308,6 +310,8 @@ class Schedule(object): self.created_count += 1 self.last = time + # TODO add option to only change one snapshot in a path, i.e. pass repeat + # and start time as well UPDATE_INACTIVE = '''UPDATE schedules SET active = 0 @@ -316,9 +320,20 @@ class Schedule(object): def set_inactive(self, db): with db: - log.debug(f'Deactivating schedule on non-existing path {self.path}') + log.debug(f'Deactivating schedule on path {self.path}') db.execute(self.UPDATE_INACTIVE, (self.path,)) + UPDATE_ACTIVE = '''UPDATE schedules + SET + active = 1 + WHERE + path = ?;''' + + def set_active(self, db): + with db: + log.debug(f'Activating schedule on path {self.path}') + db.execute(self.UPDATE_ACTIVE, (self.path,)) + UPDATE_PRUNED = '''UPDATE schedules_meta SET last_pruned = ?, @@ -517,7 +532,8 @@ class SnapSchedClient(CephfsClient): return Schedule.list_schedules(path, db, fs, recursive) @updates_schedule_db - def store_snap_schedule(self, fs, args): + # TODO improve interface + def store_snap_schedule(self, fs, path_, args): sched = Schedule(*args) log.debug(f'attempting to add schedule {sched}') db = self.get_schedule_db(fs) @@ -528,3 +544,15 @@ class SnapSchedClient(CephfsClient): def rm_snap_schedule(self, fs, path, repeat, start): db = self.get_schedule_db(fs) Schedule.rm_schedule(db, path, repeat, start) + + @updates_schedule_db + def activate_snap_schedule(self, fs, path, repeat, start): + db = self.get_schedule_db(fs) + schedules = Schedule.get_db_schedules(path, db, fs) + [s.set_active(db) for s in schedules] + + @updates_schedule_db + def deactivate_snap_schedule(self, fs, path, repeat, start): + db = self.get_schedule_db(fs) + schedules = Schedule.get_db_schedules(path, db, fs) + [s.set_inactive(db) for s in schedules] diff --git a/src/pybind/mgr/snap_schedule/module.py b/src/pybind/mgr/snap_schedule/module.py index 3173f024ffbea..ccdce515a09c4 100644 --- a/src/pybind/mgr/snap_schedule/module.py +++ b/src/pybind/mgr/snap_schedule/module.py @@ -95,7 +95,7 @@ class Module(MgrModule): try: use_fs = fs if fs else self.default_fs abs_path = self.resolve_subvolume_path(fs, subvol, path) - self.client.store_snap_schedule(use_fs, (abs_path, snap_schedule, + self.client.store_snap_schedule(use_fs, abs_path, (abs_path, snap_schedule, retention_policy, start, use_fs, subvol, path)) suc_msg = f'Schedule set for path {path}' @@ -131,3 +131,49 @@ class Module(MgrModule): except ValueError as e: return errno.ENOENT, '', str(e) return 0, 'Schedule removed for path {}'.format(path), '' + + @CLIWriteCommand('fs snap-schedule activate', + 'name=path,type=CephString ' + 'name=repeat,type=CephString,req=false ' + 'name=start,type=CephString,req=false ' + 'name=subvol,type=CephString,req=false ' + 'name=fs,type=CephString,req=false', + 'Activate a snapshot schedule for ') + def snap_schedule_activate(self, + path, + repeat=None, + start=None, + subvol=None, + fs=None): + try: + use_fs = fs if fs else self.default_fs + abs_path = self.resolve_subvolume_path(fs, subvol, path) + self.client.activate_snap_schedule(use_fs, abs_path, repeat, start) + except CephfsConnectionException as e: + return e.to_tuple() + except ValueError as e: + return errno.ENOENT, '', str(e) + return 0, 'Schedule activated for path {}'.format(path), '' + + @CLIWriteCommand('fs snap-schedule deactivate', + 'name=path,type=CephString ' + 'name=repeat,type=CephString,req=false ' + 'name=start,type=CephString,req=false ' + 'name=subvol,type=CephString,req=false ' + 'name=fs,type=CephString,req=false', + 'Deactivate a snapshot schedule for ') + def snap_schedule_deactivate(self, + path, + repeat=None, + start=None, + subvol=None, + fs=None): + try: + use_fs = fs if fs else self.default_fs + abs_path = self.resolve_subvolume_path(fs, subvol, path) + self.client.deactivate_snap_schedule(use_fs, abs_path, repeat, start) + except CephfsConnectionException as e: + return e.to_tuple() + except ValueError as e: + return errno.ENOENT, '', str(e) + return 0, 'Schedule deactivated for path {}'.format(path), ''