jaseci 1.4.2.6__py3-none-any.whl → 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of jaseci might be problematic. Click here for more details.

Files changed (187) hide show
  1. jaseci/__init__.py +3 -37
  2. jaseci-2.0.0.dist-info/METADATA +65 -0
  3. jaseci-2.0.0.dist-info/RECORD +4 -0
  4. {jaseci-1.4.2.6.dist-info → jaseci-2.0.0.dist-info}/WHEEL +1 -2
  5. jaseci/VERSION +0 -1
  6. jaseci/cli_tools/__init__.py +0 -0
  7. jaseci/cli_tools/book_tools.py +0 -457
  8. jaseci/cli_tools/jsctl.py +0 -500
  9. jaseci/cli_tools/tests/__init__.py +0 -0
  10. jaseci/cli_tools/tests/test_jsctl.py +0 -556
  11. jaseci/extens/__init__.py +0 -0
  12. jaseci/extens/act_lib/__init__.py +0 -0
  13. jaseci/extens/act_lib/date.py +0 -118
  14. jaseci/extens/act_lib/elastic.py +0 -87
  15. jaseci/extens/act_lib/file.py +0 -77
  16. jaseci/extens/act_lib/file_handler.py +0 -190
  17. jaseci/extens/act_lib/internal.py +0 -19
  18. jaseci/extens/act_lib/jaseci.py +0 -62
  19. jaseci/extens/act_lib/mail.py +0 -10
  20. jaseci/extens/act_lib/maths.py +0 -168
  21. jaseci/extens/act_lib/net.py +0 -192
  22. jaseci/extens/act_lib/rand.py +0 -83
  23. jaseci/extens/act_lib/regex.py +0 -85
  24. jaseci/extens/act_lib/request.py +0 -170
  25. jaseci/extens/act_lib/std.py +0 -236
  26. jaseci/extens/act_lib/storage.py +0 -53
  27. jaseci/extens/act_lib/stripe.py +0 -338
  28. jaseci/extens/act_lib/task.py +0 -14
  29. jaseci/extens/act_lib/tests/__init__.py +0 -0
  30. jaseci/extens/act_lib/tests/std_test_code.py +0 -37
  31. jaseci/extens/act_lib/tests/test_date.py +0 -26
  32. jaseci/extens/act_lib/tests/test_elastic.py +0 -159
  33. jaseci/extens/act_lib/tests/test_file.py +0 -116
  34. jaseci/extens/act_lib/tests/test_file_lib.py +0 -40
  35. jaseci/extens/act_lib/tests/test_mail_lib.py +0 -33
  36. jaseci/extens/act_lib/tests/test_maths.py +0 -147
  37. jaseci/extens/act_lib/tests/test_net_lib.py +0 -62
  38. jaseci/extens/act_lib/tests/test_regex.py +0 -61
  39. jaseci/extens/act_lib/tests/test_std.py +0 -51
  40. jaseci/extens/act_lib/tests/test_std_lib.py +0 -36
  41. jaseci/extens/act_lib/tests/test_url.py +0 -32
  42. jaseci/extens/act_lib/tests/test_vector.py +0 -36
  43. jaseci/extens/act_lib/tests/test_webtool.py +0 -44
  44. jaseci/extens/act_lib/tests/test_zlib.py +0 -24
  45. jaseci/extens/act_lib/url.py +0 -80
  46. jaseci/extens/act_lib/vector.py +0 -158
  47. jaseci/extens/act_lib/webtool.py +0 -29
  48. jaseci/extens/act_lib/zip.py +0 -34
  49. jaseci/extens/api/__init__.py +0 -0
  50. jaseci/extens/api/actions_api.py +0 -171
  51. jaseci/extens/api/alias_api.py +0 -140
  52. jaseci/extens/api/architype_api.py +0 -197
  53. jaseci/extens/api/config_api.py +0 -129
  54. jaseci/extens/api/global_api.py +0 -85
  55. jaseci/extens/api/graph_api.py +0 -168
  56. jaseci/extens/api/health_api.py +0 -21
  57. jaseci/extens/api/interface.py +0 -269
  58. jaseci/extens/api/jac_api.py +0 -172
  59. jaseci/extens/api/jsorc_api.py +0 -317
  60. jaseci/extens/api/logger_api.py +0 -90
  61. jaseci/extens/api/master_api.py +0 -134
  62. jaseci/extens/api/object_api.py +0 -102
  63. jaseci/extens/api/prometheus_api.py +0 -75
  64. jaseci/extens/api/queue_api.py +0 -141
  65. jaseci/extens/api/sentinel_api.py +0 -271
  66. jaseci/extens/api/share_api.py +0 -64
  67. jaseci/extens/api/super_api.py +0 -65
  68. jaseci/extens/api/tests/__init__.py +0 -0
  69. jaseci/extens/api/tests/test_architype_api.py +0 -66
  70. jaseci/extens/api/tests/test_global_api.py +0 -179
  71. jaseci/extens/api/tests/test_graph_api.py +0 -64
  72. jaseci/extens/api/tests/test_logger_api.py +0 -43
  73. jaseci/extens/api/tests/test_object_api.py +0 -20
  74. jaseci/extens/api/tests/test_sentinel_api.py +0 -66
  75. jaseci/extens/api/tests/test_uncommon.py +0 -107
  76. jaseci/extens/api/tests/test_user_api.py +0 -32
  77. jaseci/extens/api/tests/test_walker_api.py +0 -316
  78. jaseci/extens/api/user_api.py +0 -166
  79. jaseci/extens/api/walker_api.py +0 -299
  80. jaseci/extens/api/webhook_api.py +0 -77
  81. jaseci/extens/svc/__init__.py +0 -0
  82. jaseci/extens/svc/elastic_svc.py +0 -366
  83. jaseci/extens/svc/kube_svc.py +0 -432
  84. jaseci/extens/svc/mail_svc.py +0 -156
  85. jaseci/extens/svc/prome_svc.py +0 -378
  86. jaseci/extens/svc/redis_svc.py +0 -63
  87. jaseci/extens/svc/storage_svc.py +0 -193
  88. jaseci/extens/svc/stripe_svc.py +0 -51
  89. jaseci/extens/svc/task_svc.py +0 -155
  90. jaseci/extens/svc/tasks.py +0 -302
  91. jaseci/jac/__init__.py +0 -0
  92. jaseci/jac/interpreter/__init__.py +0 -0
  93. jaseci/jac/interpreter/architype_interp.py +0 -219
  94. jaseci/jac/interpreter/interp.py +0 -1784
  95. jaseci/jac/interpreter/sentinel_interp.py +0 -260
  96. jaseci/jac/interpreter/tests/__init__.py +0 -0
  97. jaseci/jac/interpreter/tests/test_interp.py +0 -42
  98. jaseci/jac/interpreter/walker_interp.py +0 -249
  99. jaseci/jac/ir/__init__.py +0 -0
  100. jaseci/jac/ir/ast.py +0 -73
  101. jaseci/jac/ir/ast_builder.py +0 -249
  102. jaseci/jac/ir/jac_code.py +0 -151
  103. jaseci/jac/ir/passes/__init__.py +0 -6
  104. jaseci/jac/ir/passes/ast_prune_pass.py +0 -9
  105. jaseci/jac/ir/passes/codegen_pass.py +0 -244
  106. jaseci/jac/ir/passes/ir_pass.py +0 -29
  107. jaseci/jac/ir/passes/printer_pass.py +0 -23
  108. jaseci/jac/ir/passes/pt_prune_pass.py +0 -29
  109. jaseci/jac/ir/passes/schedule.py +0 -23
  110. jaseci/jac/ir/passes/stats_pass.py +0 -16
  111. jaseci/jac/jac.g4 +0 -450
  112. jaseci/jac/jac_parse/__init__.py +0 -0
  113. jaseci/jac/jac_parse/jacLexer.py +0 -809
  114. jaseci/jac/jac_parse/jacListener.py +0 -853
  115. jaseci/jac/jac_parse/jacParser.py +0 -9192
  116. jaseci/jac/jac_set.py +0 -120
  117. jaseci/jac/jsci_vm/__init__.py +0 -0
  118. jaseci/jac/jsci_vm/disasm.py +0 -94
  119. jaseci/jac/jsci_vm/inst_ptr.py +0 -31
  120. jaseci/jac/jsci_vm/machine.py +0 -188
  121. jaseci/jac/jsci_vm/op_codes.py +0 -82
  122. jaseci/jac/jsci_vm/tests/__init__.py +0 -0
  123. jaseci/jac/jsci_vm/tests/test_codegen.py +0 -31
  124. jaseci/jac/machine/__init__.py +0 -0
  125. jaseci/jac/machine/jac_scope.py +0 -86
  126. jaseci/jac/machine/jac_value.py +0 -227
  127. jaseci/jac/machine/machine_state.py +0 -386
  128. jaseci/jac/tests/__init__.py +0 -0
  129. jaseci/jac/tests/book_code.py +0 -624
  130. jaseci/jac/tests/test_book.py +0 -380
  131. jaseci/jac/tests/test_lang_14.py +0 -49
  132. jaseci/jsorc/__init__.py +0 -7
  133. jaseci/jsorc/jsorc.py +0 -642
  134. jaseci/jsorc/jsorc_settings.py +0 -211
  135. jaseci/jsorc/jsorc_utils.py +0 -298
  136. jaseci/jsorc/live_actions.py +0 -365
  137. jaseci/jsorc/manifests/__init__.py +0 -0
  138. jaseci/jsorc/manifests/database.yaml +0 -109
  139. jaseci/jsorc/manifests/elastic.yaml +0 -6029
  140. jaseci/jsorc/manifests/prometheus.yaml +0 -1383
  141. jaseci/jsorc/manifests/redis.yaml +0 -64
  142. jaseci/jsorc/memory.py +0 -258
  143. jaseci/jsorc/redis.py +0 -140
  144. jaseci/jsorc/remote_actions.py +0 -158
  145. jaseci/jsorc/tests/__init__.py +0 -0
  146. jaseci/jsorc/tests/test_actions.py +0 -542
  147. jaseci/jsorc/tests/test_jsorc.py +0 -112
  148. jaseci/prim/__init__.py +0 -0
  149. jaseci/prim/ability.py +0 -94
  150. jaseci/prim/architype.py +0 -90
  151. jaseci/prim/edge.py +0 -173
  152. jaseci/prim/element.py +0 -233
  153. jaseci/prim/graph.py +0 -27
  154. jaseci/prim/master.py +0 -67
  155. jaseci/prim/node.py +0 -533
  156. jaseci/prim/obj_mixins.py +0 -238
  157. jaseci/prim/sentinel.py +0 -282
  158. jaseci/prim/super_master.py +0 -31
  159. jaseci/prim/walker.py +0 -261
  160. jaseci/svc/__init__.py +0 -0
  161. jaseci/tests/__init__.py +0 -0
  162. jaseci/tests/infer.py +0 -39
  163. jaseci/tests/jac_test_code.py +0 -1293
  164. jaseci/tests/jac_test_progs.py +0 -774
  165. jaseci/tests/test_core.py +0 -153
  166. jaseci/tests/test_jac.py +0 -824
  167. jaseci/tests/test_node.py +0 -89
  168. jaseci/tests/test_progs.py +0 -702
  169. jaseci/tests/test_stack.py +0 -220
  170. jaseci/tests/test_stripe.py +0 -225
  171. jaseci/utils/__init__.py +0 -0
  172. jaseci/utils/actions/__init__.py +0 -0
  173. jaseci/utils/actions/actions_manager.py +0 -254
  174. jaseci/utils/actions/actions_optimizer.py +0 -517
  175. jaseci/utils/actions/actions_state.py +0 -95
  176. jaseci/utils/file_handler.py +0 -171
  177. jaseci/utils/gprof2dot.py +0 -3786
  178. jaseci/utils/id_list.py +0 -169
  179. jaseci/utils/json_handler.py +0 -70
  180. jaseci/utils/log_utils.py +0 -57
  181. jaseci/utils/test_core.py +0 -62
  182. jaseci/utils/utils.py +0 -387
  183. jaseci-1.4.2.6.dist-info/LICENSE +0 -21
  184. jaseci-1.4.2.6.dist-info/METADATA +0 -39
  185. jaseci-1.4.2.6.dist-info/RECORD +0 -185
  186. jaseci-1.4.2.6.dist-info/entry_points.txt +0 -3
  187. jaseci-1.4.2.6.dist-info/top_level.txt +0 -1
jaseci/jsorc/jsorc.py DELETED
@@ -1,642 +0,0 @@
1
- import signal
2
- import psycopg2
3
-
4
- from time import sleep
5
- from copy import deepcopy
6
- from json import dumps
7
- from datetime import datetime
8
- from typing import TypeVar, Any, Union
9
-
10
- from jaseci.utils.utils import logger
11
- from jaseci.jsorc.jsorc_settings import JsOrcSettings
12
- from jaseci.jsorc.jsorc_utils import State, CommonService as cs, ManifestType
13
-
14
- from kubernetes.client.rest import ApiException
15
-
16
- # For future use
17
- # from concurrent.futures import ThreadPoolExecutor
18
- # from os import cpu_count
19
-
20
- T = TypeVar("T")
21
-
22
-
23
- class JsOrc:
24
- # ------------------- ALIAS ------------------- #
25
-
26
- CommonService = cs
27
-
28
- # ----------------- REFERENCE ----------------- #
29
-
30
- _contexts = {}
31
- _context_instances = {}
32
-
33
- _services = {}
34
- _service_instances = {}
35
-
36
- _repositories = {}
37
-
38
- # ----------------- SETTINGS ----------------- #
39
-
40
- _use_proxy = False
41
- _settings = JsOrcSettings
42
-
43
- # For future use
44
- # _executor = ThreadPoolExecutor(
45
- # min(4, int((cpu_count() or 2) / 4) + 1)
46
- # )
47
-
48
- # ------------------ COMMONS ------------------ #
49
-
50
- _config = None
51
- _backoff_interval = 10
52
- _running_interval = 0
53
- __running__ = False
54
- __proxy__ = cs.proxy()
55
-
56
- # ------------------- REGEN ------------------- #
57
-
58
- _regeneration_queues = []
59
- _regenerating = False
60
- _has_db = False
61
-
62
- @staticmethod
63
- def push(name: str, target: dict, entry: dict):
64
- if name not in target:
65
- target[name] = [entry]
66
- else:
67
- target[name] = sorted(
68
- target[name] + [entry],
69
- key=lambda item: (-item["priority"], -item["date_added"]),
70
- )
71
-
72
- @classmethod
73
- def configure(cls):
74
- config: dict = cls.settings("JSORC_CONFIG")
75
-
76
- if cls.db_check():
77
- hook = cls.hook()
78
- config = hook.get_or_create_glob("JSORC_CONFIG", config)
79
-
80
- cls._config = config
81
- cls._backoff_interval = max(5, config.get("backoff_interval", 10))
82
- cls._regeneration_queues = config.get("pre_loaded_services", [])
83
-
84
- @classmethod
85
- def run(cls):
86
- if not cls.__running__:
87
- cls.__running__ = True
88
- cls.configure()
89
- cls.push_interval(1)
90
-
91
- @classmethod
92
- def push_interval(cls, interval):
93
- if cls._running_interval == 0:
94
- cls._running_interval += 1
95
- signal.alarm(interval)
96
- else:
97
- logger.info("Reusing current running interval...")
98
-
99
- @classmethod
100
- def kube(cls):
101
- if not cls._kube:
102
- raise Exception(f"Kubernetes is not yet ready!")
103
- return cls._kube
104
-
105
- #################################################
106
- # HELPER #
107
- #################################################
108
-
109
- # ------------------ context ------------------ #
110
-
111
- @classmethod
112
- def get(cls, context: str, cast: T = None, *args, **kwargs) -> Union[T, Any]:
113
- """
114
- Get existing context instance or build a new one that will persists
115
- ex: master
116
-
117
- context: name of the context to be build
118
- cast: to cast the return and allow code hinting
119
- *arsgs: additional argument used to initialize context
120
- **kwargs: additional keyword argument used to initialize context
121
- """
122
- if context not in cls._contexts:
123
- raise Exception(f"Context {context} is not existing!")
124
-
125
- if context not in cls._context_instances:
126
- cls._context_instances[context] = cls.ctx(context, cast, *args, **kwargs)
127
-
128
- return cls._context_instances[context]
129
-
130
- @classmethod
131
- def destroy(cls, context: str):
132
- """
133
- remove existing context instance
134
- ex: master
135
-
136
- context: name of the context to be build
137
- """
138
- if context not in cls._contexts:
139
- raise Exception(f"Context {context} is not existing!")
140
-
141
- if context in cls._context_instances:
142
- del cls._context_instances[context]
143
-
144
- @classmethod
145
- def renew(cls, context: str, cast: T = None, *args, **kwargs) -> Union[T, Any]:
146
- """
147
- renew existing context instance or build a new one that will persists
148
- ex: master
149
-
150
- context: name of the context to be build
151
- cast: to cast the return and allow code hinting
152
- *arsgs: additional argument used to initialize context
153
- **kwargs: additional keyword argument used to initialize context
154
- """
155
- cls.destroy(context)
156
-
157
- cls._context_instances[context] = cls.ctx(context, cast, *args, **kwargs)
158
- return cls._context_instances[context]
159
-
160
- @classmethod
161
- def ctx(cls, context: str, cast: T = None, *args, **kwargs) -> Union[T, Any]:
162
- """
163
- Build new instance of the context
164
- ex: master
165
-
166
- context: name of the context to be build
167
- cast: to cast the return and allow code hinting
168
- *arsgs: additional argument used to initialize context
169
- **kwargs: additional keyword argument used to initialize context
170
- """
171
- if context not in cls._contexts:
172
- raise Exception(f"Context {context} is not existing!")
173
-
174
- # highest priority
175
- context = cls._contexts[context][0]
176
-
177
- return context["type"](*args, **kwargs)
178
-
179
- @classmethod
180
- def ctx_cls(cls, context: str):
181
- """
182
- Get the context class
183
- """
184
- if context not in cls._contexts:
185
- return None
186
-
187
- return cls._contexts[context][0]["type"]
188
-
189
- @classmethod
190
- def master(cls, cast: T = None, *args, **kwargs) -> Union[T, Any]:
191
- """
192
- Generate master instance
193
- """
194
- return cls.__gen_with_hook("master", cast, *args, **kwargs)
195
-
196
- @classmethod
197
- def super_master(cls, cast: T = None, *args, **kwargs) -> Union[T, Any]:
198
- """
199
- Generate super_master instance
200
- """
201
- return cls.__gen_with_hook("super_master", cast, *args, **kwargs)
202
-
203
- @classmethod
204
- def __gen_with_hook(cls, context: str, *args, **kwargs):
205
- """
206
- Common process on master and super_master
207
- """
208
- if not kwargs.get("h", None):
209
- kwargs["h"] = cls.hook()
210
-
211
- return cls.ctx(context, None, *args, **kwargs)
212
-
213
- # ------------------ service ------------------ #
214
-
215
- @classmethod
216
- def _svc(cls, service: str) -> cs:
217
- if service not in cls._services:
218
- raise Exception(f"Service {service} is not existing!")
219
-
220
- # highest priority
221
- instance = cls._services[service][0]
222
-
223
- config = cls.settings(instance["config"], cls.settings("DEFAULT_CONFIG"))
224
- manifest = cls.settings(
225
- instance["manifest"] or "DEFAULT_MANIFEST", cls.settings("DEFAULT_MANIFEST")
226
- )
227
-
228
- if cls.db_check():
229
- hook = cls.hook(use_proxy=instance["proxy"])
230
-
231
- config = hook.get_or_create_glob(instance["config"], config)
232
-
233
- manifest = (
234
- hook.get_or_create_glob(instance["manifest"], manifest)
235
- if instance["manifest"]
236
- else {}
237
- )
238
-
239
- instance: cs = instance["type"](
240
- config, manifest, instance["manifest_type"], instance
241
- )
242
-
243
- if instance.has_failed() and service not in cls._regeneration_queues:
244
- cls._regeneration_queues.append(service)
245
-
246
- return instance
247
-
248
- @classmethod
249
- def svc(cls, service: str, cast: T = None) -> Union[T, cs]:
250
- """
251
- Get service. Initialize when not yet existing.
252
- ex: task
253
-
254
- service: name of the service to be reference
255
- cast: to cast the return and allow code hinting
256
- """
257
- if service not in cls._services:
258
- raise Exception(f"Service {service} is not existing!")
259
-
260
- if service not in cls._service_instances:
261
- if cls._use_proxy and cls._services[service][0]["proxy"]:
262
- return cls.__proxy__
263
- cls._service_instances[service] = cls._svc(service)
264
-
265
- return cls._service_instances[service]
266
-
267
- @classmethod
268
- def svc_conf_set(
269
- cls, service: str, config: dict, hook: None, cast: T = None
270
- ) -> Union[T, cs]:
271
- from jaseci.extens.svc.kube_svc import KubeService
272
-
273
- if service not in cls._services:
274
- raise Exception(f"Service {service} is not existing!")
275
-
276
- if cls.db_check():
277
- instance = cls._services[service][0]
278
- hook = hook or cls.hook(use_proxy=instance["proxy"])
279
- hook.save_glob(instance["config"], dumps(config))
280
- hook.commit()
281
-
282
- kube = cls.svc("kube", KubeService)
283
- if kube.is_running() and kube.has_replicas():
284
- hook.clear_cache(True)
285
- return (
286
- "Rollout restart commencing..."
287
- if not isinstance(kube.restart(), ApiException)
288
- else "Attempt to rollout restart failed! Please check the logs for further information!"
289
- )
290
-
291
- return cls.svc_reset(service).info()
292
-
293
- @classmethod
294
- def svc_reset(cls, service, cast: T = None) -> Union[T, cs]:
295
- """
296
- Service reset now deletes the actual instance and rebuild it
297
- """
298
- if service in cls._service_instances:
299
- instance = cls._service_instances.pop(service)
300
- del instance
301
- return cls.svc(service)
302
-
303
- # ---------------- repository ----------------- #
304
-
305
- @classmethod
306
- def src(cls, repository: str, cast: T = None) -> Union[T, Any]:
307
- """
308
- Initialize datasource class (repository)
309
- ex: hook
310
-
311
- repository: name of the repository to be reference
312
- cast: to cast the return and allow code hinting
313
- """
314
- if repository not in cls._repositories:
315
- raise Exception(f"Repository {repository} is not existing!")
316
-
317
- # highest priority
318
- repository = cls._repositories[repository][0]
319
-
320
- return repository["type"]()
321
-
322
- @classmethod
323
- def hook(cls, cast: T = None, use_proxy: bool = False) -> Union[T, Any]:
324
- """
325
- Generate hook repository instance
326
- """
327
- cls._use_proxy = use_proxy
328
- hook = cls.src("hook")
329
- cls._use_proxy = False
330
- return hook
331
-
332
- #################################################
333
- # DECORATORS #
334
- #################################################
335
-
336
- @classmethod
337
- def service(
338
- cls,
339
- name: str = None,
340
- config: str = None,
341
- manifest: str = None,
342
- manifest_type: ManifestType = ManifestType.DEDICATED,
343
- priority: int = 0,
344
- proxy: bool = False,
345
- ):
346
- """
347
- Save the class in services options
348
- name: name to be used for reference
349
- config: config name from datasource
350
- manifest: manifest name from datasource
351
- priority: duplicate name will use the highest priority
352
- proxy: allow proxy service
353
- manifest_type: manifest process type
354
- """
355
-
356
- def decorator(service: T) -> T:
357
- cls.push(
358
- name=name or service.__name__,
359
- target=cls._services,
360
- entry={
361
- "type": service,
362
- "config": (config or f"{name}_CONFIG").upper(),
363
- "manifest": manifest,
364
- "manifest_type": manifest_type,
365
- "priority": priority,
366
- "proxy": proxy,
367
- "date_added": int(datetime.utcnow().timestamp() * 1000),
368
- },
369
- )
370
- return service
371
-
372
- return decorator
373
-
374
- @classmethod
375
- def repository(cls, name: str = None, priority: int = 0):
376
- """
377
- Save the class in repositories options
378
- name: name to be used for reference
379
- priority: duplicate name will use the highest priority
380
- """
381
-
382
- def decorator(repository: T) -> T:
383
- cls.push(
384
- name=name or repository.__name__,
385
- target=cls._repositories,
386
- entry={
387
- "type": repository,
388
- "priority": priority,
389
- "date_added": int(datetime.utcnow().timestamp() * 1000),
390
- },
391
- )
392
- return repository
393
-
394
- return decorator
395
-
396
- @classmethod
397
- def context(cls, name: str = None, priority: int = 0):
398
- """
399
- Save the class in contexts options
400
- name: name to be used for reference
401
- priority: duplicate name will use the highest priority
402
- """
403
-
404
- def decorator(context: T) -> T:
405
- cls.push(
406
- name=name or context.__name__,
407
- target=cls._contexts,
408
- entry={
409
- "type": context,
410
- "priority": priority,
411
- "date_added": int(datetime.utcnow().timestamp() * 1000),
412
- },
413
- )
414
- return context
415
-
416
- return decorator
417
-
418
- @classmethod
419
- def inject(cls, contexts: list = [], services: list = [], repositories: list = []):
420
- """
421
- Allow to inject instance on specific method/class
422
- contexts: list of context name to inject
423
- - can use tuple per entry (name, alias) instead of string
424
- services: list of service name to inject
425
- - can use tuple per entry (name, alias) instead of string
426
- repositories: list of service name to inject
427
- - can use tuple per entry (name, alias) instead of string
428
- """
429
-
430
- def decorator(callable):
431
- def argument_handler(*args, **kwargs):
432
- _instances = {}
433
-
434
- for context in contexts:
435
- if isinstance(context, tuple):
436
- _instances[context[1]] = cls.ctx(context[0])
437
- else:
438
- _instances[context] = cls.ctx(context)
439
- for repository in repositories:
440
- if isinstance(repository, tuple):
441
- _instances[repository[1]] = cls.src(repository[0])
442
- else:
443
- _instances[repository] = cls.src(repository)
444
- for service in services:
445
- if isinstance(service, tuple):
446
- _instances[service[1]] = cls.svc(service[0])
447
- else:
448
- _instances[service] = cls.svc(service)
449
-
450
- kwargs.update(_instances)
451
- callable(*args, **kwargs)
452
-
453
- return argument_handler
454
-
455
- return decorator
456
-
457
- @classmethod
458
- def settings(cls, name: str, default: T = None) -> Union[T, Any]:
459
- return getattr(cls._settings, name, default)
460
-
461
- @classmethod
462
- def overrided_namespace(
463
- cls, name: str, manifest_type: ManifestType = ManifestType.DEDICATED
464
- ) -> tuple:
465
- manual_namespace = cls.settings("SERVICE_MANIFEST_MAP").get(name)
466
- if manual_namespace:
467
- if manual_namespace == "SOURCE":
468
- manifest_type = ManifestType.SOURCE
469
- else:
470
- manual_namespace == manual_namespace.lower()
471
- manifest_type = ManifestType.MANUAL
472
- return manifest_type, manual_namespace
473
-
474
- return (manifest_type,)
475
-
476
- #################################################
477
- # AUTOMATION #
478
- #################################################
479
-
480
- @classmethod
481
- def add_regeneration_queue(cls, service: str):
482
- cls.svc(service).state = State.RESTART
483
- cls._regeneration_queues.append(service)
484
-
485
- @classmethod
486
- def regenerate(cls):
487
- if not cls._regenerating:
488
- cls._regenerating = True
489
-
490
- if cls._has_db:
491
- cls.regenerate_service()
492
- else:
493
- cls.regenerate_database()
494
-
495
- cls._regenerating = False
496
-
497
- @classmethod
498
- def regenerate_service(cls):
499
- from jaseci.extens.svc.kube_svc import KubeService
500
- from jaseci.utils.actions.actions_manager import ActionManager
501
-
502
- kube = cls.svc("kube", KubeService)
503
- regeneration_queues = cls._regeneration_queues.copy()
504
- cls._regeneration_queues.clear()
505
- while regeneration_queues:
506
- regeneration_queue = regeneration_queues.pop(0)
507
- service = cls.svc(regeneration_queue)
508
- hook = cls.hook(use_proxy=service.source["proxy"])
509
- if not service.is_running() and service.enabled and service.automated:
510
- if service.manifest and kube.is_running():
511
- try:
512
- manifest = kube.resolve_manifest(
513
- hook.get_or_create_glob(
514
- service.source["manifest"], service.manifest
515
- ),
516
- *cls.overrided_namespace(
517
- regeneration_queue, service.manifest_type
518
- ),
519
- )
520
-
521
- rmhists: dict = hook.get_or_create_glob(
522
- "RESOLVED_MANIFEST_HISTORY", {}
523
- )
524
-
525
- _rmhist = rmhists.get(service.source["manifest"], [{}])[0]
526
- rmhist = deepcopy(_rmhist)
527
-
528
- for kind, confs in manifest.items():
529
- for name, conf in confs.items():
530
- namespace = conf["metadata"].get("namespace")
531
-
532
- if kind in rmhist and name in rmhist[kind]:
533
- rmhist[kind].pop(name, None)
534
-
535
- res = kube.read(kind, name, namespace)
536
- if hasattr(res, "status") and res.status == 404:
537
- kube.create(kind, name, conf, namespace)
538
- elif not isinstance(res, ApiException):
539
- config_version = 1
540
-
541
- if isinstance(res, dict):
542
- if "labels" in res["metadata"]:
543
- config_version = (
544
- res["metadata"]
545
- .get("labels", {})
546
- .get("config_version", 1)
547
- )
548
- elif res.metadata.labels:
549
- config_version = res.metadata.labels.get(
550
- "config_version", 1
551
- )
552
-
553
- if config_version != conf.get("metadata").get(
554
- "labels", {}
555
- ).get("config_version", 1):
556
- kube.patch(kind, name, conf, namespace)
557
-
558
- for kind, confs in rmhist.items():
559
- for name, conf in confs.items():
560
- namespace = conf["metadata"].get("namespace")
561
- res = kube.read(kind, name, namespace, quiet=True)
562
- if not isinstance(res, ApiException) and (
563
- (isinstance(res, dict) and res.get("metadata"))
564
- or res.metadata
565
- ):
566
- if kind not in cls.settings(
567
- "UNSAFE_KINDS"
568
- ) or service.manifest_unsafe_paraphrase == cls.settings(
569
- "UNSAFE_PARAPHRASE"
570
- ):
571
- kube.delete(kind, name, namespace)
572
- else:
573
- logger.info(
574
- f"You don't have permission to delete `{kind}` for `{name}` with namespace `{namespace}`!"
575
- )
576
-
577
- if _rmhist != manifest:
578
- if service.source["manifest"] not in rmhists:
579
- rmhists[service.source["manifest"]] = [manifest]
580
- else:
581
- rmhists[service.source["manifest"]].insert(0, manifest)
582
- hook.save_glob("RESOLVED_MANIFEST_HISTORY", dumps(rmhists))
583
- hook.commit()
584
-
585
- except Exception as e:
586
- logger.error(f"Unhandled exception: {e}")
587
-
588
- cls.svc_reset(regeneration_queue)
589
-
590
- action_manager = cls.get("action_manager", ActionManager)
591
- action_manager.optimize(jsorc_interval=cls._backoff_interval)
592
- action_manager.record_system_state()
593
-
594
- @classmethod
595
- def regenerate_database(cls):
596
- from jaseci.extens.svc.kube_svc import KubeService
597
-
598
- kube = cls.svc("kube", KubeService)
599
-
600
- if kube.is_running():
601
- while not cls.db_check():
602
- for kind, confs in kube.resolve_manifest(
603
- cls.settings("DB_REGEN_MANIFEST", {}),
604
- *cls.overrided_namespace("database"),
605
- ).items():
606
- for name, conf in confs.items():
607
- namespace = conf["metadata"].get("namespace")
608
- res = kube.read(kind, name, namespace)
609
- if hasattr(res, "status") and res.status == 404 and conf:
610
- kube.create(kind, name, conf, namespace)
611
- sleep(1)
612
- raise SystemExit("Force termination to restart the pod!")
613
-
614
- @classmethod
615
- def db_check(cls):
616
- if not cls._has_db:
617
- try:
618
- dbrc = cls.settings("DB_REGEN_CONFIG")
619
- if dbrc["enabled"]:
620
- connection = psycopg2.connect(
621
- host=dbrc["host"],
622
- dbname=dbrc["db"],
623
- user=dbrc["user"],
624
- password=dbrc["password"],
625
- port=dbrc["port"],
626
- )
627
- connection.close()
628
- cls._has_db = True
629
- except Exception:
630
- cls._has_db = False
631
- return cls._has_db
632
-
633
-
634
- def interval_check(signum, frame):
635
- JsOrc.regenerate()
636
-
637
- # wait interval_check to be finished before decrement
638
- JsOrc._running_interval -= 1
639
- JsOrc.push_interval(JsOrc._backoff_interval)
640
-
641
-
642
- signal.signal(signal.SIGALRM, interval_check)