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
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:
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
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 = ?,
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)
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]
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}'
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 <path>')
+ 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 <path>')
+ 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), ''