Update README.md to specify the python requirements
[time-slider.git] / usr / share / time-slider / lib / time_slider / linux / autosnapsmf.py
1 #!/usr/bin/python3
2 #
3 # CDDL HEADER START
4 #
5 # The contents of this file are subject to the terms of the
6 # Common Development and Distribution License (the "License").
7 # You may not use this file except in compliance with the License.
8 #
9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 # or http://www.opensolaris.org/os/licensing.
11 # See the License for the specific language governing permissions
12 # and limitations under the License.
13 #
14 # When distributing Covered Code, include this CDDL HEADER in each
15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 # If applicable, add the following below this CDDL HEADER, with the
17 # fields enclosed by brackets "[]" replaced with your own identifying
18 # information: Portions Copyright [yyyy] [name of copyright owner]
19 #
20 # CDDL HEADER END
21 #
22
23 import time_slider.autosnapsmf as base
24 from . import smf
25 from .timesliderconfig import Config
26
27 SNAPLABELPREFIX = base.SNAPLABELPREFIX
28
29 def get_default_schedules():
30     """
31     Finds the default schedules that are enabled (online, offline or degraded)
32     """
33     #This is not the fastest method but it is the safest, we need
34     #to ensure that default schedules are processed in the pre-defined
35     #order to ensure that the overlap between them is adhered to
36     #correctly. monthly->weekly->daily->hourly->frequent. They have
37     #to be processed first and they HAVE to be in the correct order.
38     _defaultSchedules = []
39     for s in base.factoryDefaultSchedules:
40         instanceName = "%s:%s" % (base.BASESVC,s)
41         config = Config()
42         result = config.get(instanceName[5:], "state")
43         #
44         # Note that the schedules, being dependent on the time-slider service
45         # itself will typically be in an offline state when enabled. They will
46         # transition to an "online" state once time-slider itself comes
47         # "online" to satisfy it's dependency
48         if result == "online" or result == "offline" or result == "degraded":
49             instance = AutoSnap(s)
50             try:
51                 _defaultSchedules.append(instance.get_schedule_details())
52             except RuntimeError as message:
53                 raise RuntimeError("Error getting schedule details for " + \
54                                     "default auto-snapshot SMF instance:" + \
55                                     "\n\t" + instanceName + "\nDetails:\n" + \
56                                     str(message))
57     return _defaultSchedules
58
59
60 def get_custom_schedules():
61     """
62     Finds custom schedules ie. not the factory default
63     'monthly', 'weekly', 'hourly', 'daily' and 'frequent' schedules
64     """
65     _customSchedules = []
66     config = Config()
67     for section in config.sections():
68         if section.startswith(base.BASESVC[5:]):
69             frmi = section.rsplit(":", 1)
70             label = frmi[1]
71             state = config.get(section, "state")
72
73             if label not in base.factoryDefaultSchedules:
74             # Note that the schedules, being dependent on the time-slider service
75             # itself will typically be in an offline state when enabled. They will
76             # transition to an "online" state once time-slider itself comes
77             # "online" to satisfy it's dependency
78                 if state == "online" or state == "offline" or state == "degraded":
79                     instance = AutoSnap(label)
80                     try:
81                         _customSchedules.append(instance.get_schedule_details())
82                     except RuntimeError as message:
83                         raise RuntimeError("Error getting schedule details " + \
84                                             "for custom auto-snapshot SMF " + \
85                                             "instance:\n\t" + label + "\n" + \
86                                             "Details:\n" + str(message))
87     return _customSchedules
88
89 class AutoSnap(base.AutoSnap):
90
91     def __init__(self, schedule):
92         base.AutoSnap.__init__(self, schedule)
93
94 #
95 # This is beyond ugly.
96 #
97 # The problem this is trying to solve is to change the inheritance chain. Origially
98 # it looks like this:
99 #
100 # <class 'time_slider.linux.autosnapsmf.AutoSnap'>
101 # <class 'time_slider.autosnapsmf.AutoSnap'>
102 # <class 'time_slider.smf.SMFInstance'>
103 # <type 'exceptions.Exception'>
104 # <type 'exceptions.BaseException'>
105 # <type 'object'>
106 #
107 # We'd like it to look like this:
108 #
109 # <class 'time_slider.linux.autosnapsmf.AutoSnap'>
110 # <class 'time_slider.autosnapsmf.AutoSnap'>
111 # <class 'time_slider.linux.smf.SMFInstance'>
112 # <class 'time_slider.smf.SMFInstance'>
113 # <type 'exceptions.Exception'>
114 # <type 'exceptions.BaseException'>
115 # <type 'object'>
116 #
117 # so we can inject some linux specific things into SMF without having to copy all
118 # the code.
119 #
120 # This has to be done here as the __init__ of AutoSnap will otherwise fail.
121 #
122
123 base.AutoSnap.__bases__ = (smf.SMFInstance,)
124
125 if __name__ == "__main__":
126     defaults = get_default_schedules()
127     for sched in defaults:
128         S = AutoSnap(sched[0])
129         print(S.get_schedule_details())