python-watcher 12.0.0.0rc1__py3-none-any.whl → 13.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.
- {python_watcher-12.0.0.0rc1.dist-info → python_watcher-13.0.0.dist-info}/AUTHORS +2 -0
- {python_watcher-12.0.0.0rc1.dist-info → python_watcher-13.0.0.dist-info}/METADATA +1 -1
- {python_watcher-12.0.0.0rc1.dist-info → python_watcher-13.0.0.dist-info}/RECORD +16 -16
- python_watcher-13.0.0.dist-info/pbr.json +1 -0
- watcher/db/sqlalchemy/alembic/versions/0f6042416884_add_apscheduler_jobs.py +1 -1
- watcher/db/sqlalchemy/api.py +23 -21
- watcher/db/sqlalchemy/job_store.py +29 -12
- python_watcher-12.0.0.0rc1.dist-info/pbr.json +0 -1
- {python_watcher-12.0.0.0rc1.data → python_watcher-13.0.0.data}/data/etc/apache2/watcher +0 -0
- {python_watcher-12.0.0.0rc1.data → python_watcher-13.0.0.data}/data/etc/watcher/README-watcher.conf.txt +0 -0
- {python_watcher-12.0.0.0rc1.data → python_watcher-13.0.0.data}/data/etc/watcher/oslo-config-generator/watcher.conf +0 -0
- {python_watcher-12.0.0.0rc1.data → python_watcher-13.0.0.data}/data/etc/watcher/oslo-policy-generator/watcher-policy-generator.conf +0 -0
- {python_watcher-12.0.0.0rc1.data → python_watcher-13.0.0.data}/scripts/watcher-api-wsgi +0 -0
- {python_watcher-12.0.0.0rc1.dist-info → python_watcher-13.0.0.dist-info}/LICENSE +0 -0
- {python_watcher-12.0.0.0rc1.dist-info → python_watcher-13.0.0.dist-info}/WHEEL +0 -0
- {python_watcher-12.0.0.0rc1.dist-info → python_watcher-13.0.0.dist-info}/entry_points.txt +0 -0
- {python_watcher-12.0.0.0rc1.dist-info → python_watcher-13.0.0.dist-info}/top_level.txt +0 -0
|
@@ -47,6 +47,7 @@ Ian Wienand <iwienand@redhat.com>
|
|
|
47
47
|
Iswarya_Vakati <v.iswarya@nectechnologies.in>
|
|
48
48
|
Jaewoo Park <jp655p@att.com>
|
|
49
49
|
James E. Blair <jeblair@redhat.com>
|
|
50
|
+
James Page <james.page@canonical.com>
|
|
50
51
|
Jean-Emile DARTOIS <jean-emile.dartois@b-com.com>
|
|
51
52
|
Jeremy Liu <liujiong@gohighsec.com>
|
|
52
53
|
Joe Cropper <jwcroppe@us.ibm.com>
|
|
@@ -87,6 +88,7 @@ Steve Wilkerson <sw5822@att.com>
|
|
|
87
88
|
Sumit Jamgade <sjamgade@suse.com>
|
|
88
89
|
Susanne Balle <sleipnir012@gmail.com>
|
|
89
90
|
Swapnil Kulkarni (coolsvap) <me@coolsvap.net>
|
|
91
|
+
Takashi Kajinami <kajinamit@oss.nttdata.com>
|
|
90
92
|
Takashi Kajinami <tkajinam@redhat.com>
|
|
91
93
|
Tatiana Kholkina <holkina@selectel.ru>
|
|
92
94
|
Taylor Peoples <tpeoples@us.ibm.com>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-watcher
|
|
3
|
-
Version:
|
|
3
|
+
Version: 13.0.0
|
|
4
4
|
Summary: OpenStack Watcher provides a flexible and scalable resource optimization service for multi-tenant OpenStack-based clouds.
|
|
5
5
|
Home-page: https://docs.openstack.org/watcher/latest/
|
|
6
6
|
Author: OpenStack
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
python_watcher-
|
|
2
|
-
python_watcher-
|
|
3
|
-
python_watcher-
|
|
4
|
-
python_watcher-
|
|
5
|
-
python_watcher-
|
|
1
|
+
python_watcher-13.0.0.data/data/etc/apache2/watcher,sha256=urybYUTb0kAVIvbm4WK5oDfXR82QSK2lyMl4Z9dCz4Q,1190
|
|
2
|
+
python_watcher-13.0.0.data/data/etc/watcher/README-watcher.conf.txt,sha256=EIa_sjXDyl1XSg0ovsFwUjqw0euS0N2PYn4HtyBGJME,131
|
|
3
|
+
python_watcher-13.0.0.data/data/etc/watcher/oslo-config-generator/watcher.conf,sha256=O7g1DZqgXvbQgkBfot0dR1ar1d-3SBkOU_ZK4Dz7SFc,406
|
|
4
|
+
python_watcher-13.0.0.data/data/etc/watcher/oslo-policy-generator/watcher-policy-generator.conf,sha256=ZfIuVdtrj7IZm2BrRQvAW3JOL_kqCiILf-vBmwX3ufw,76
|
|
5
|
+
python_watcher-13.0.0.data/scripts/watcher-api-wsgi,sha256=YcIpUO3iRVW6Fu3Md_ooAeHkmJJasG031naMdf8cv2A,1829
|
|
6
6
|
watcher/__init__.py,sha256=Vs2olXPZ_IAV1rukHYRl3ITzYFBNXX9mIUtFXkMWYwg,640
|
|
7
7
|
watcher/_i18n.py,sha256=-25OcpwjDCiYdFIUJh86S7Sg0fs3wMIIjEreaGUyCyY,1295
|
|
8
8
|
watcher/version.py,sha256=3bUsLHmwjNgOJ9hfzy5yQ67UGFOriUNFJqyh8lGQazE,760
|
|
@@ -142,15 +142,15 @@ watcher/db/migration.py,sha256=luOV_QnQp1XvtKFrgIMmrn7NFPbOgIcDxOBDQt5wVzE,1636
|
|
|
142
142
|
watcher/db/purge.py,sha256=cqC37xAcb18pEAdneQUcHdLMv8ZpC6FCS2iKr-CNmAQ,16858
|
|
143
143
|
watcher/db/sqlalchemy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
144
144
|
watcher/db/sqlalchemy/alembic.ini,sha256=LzCgKVKhFQctG7OUdDzWHGKnwA7WkTCLame3foHscuE,975
|
|
145
|
-
watcher/db/sqlalchemy/api.py,sha256=
|
|
146
|
-
watcher/db/sqlalchemy/job_store.py,sha256=
|
|
145
|
+
watcher/db/sqlalchemy/api.py,sha256=oFTonnHfPQ38NIRqoBgPs1J7OB1BW1qdjFrrMNJz_KE,44371
|
|
146
|
+
watcher/db/sqlalchemy/job_store.py,sha256=LTRYP2pq5Lhkpuk9Bl20QZlxdaddA-GicEOT8uW-IPo,5407
|
|
147
147
|
watcher/db/sqlalchemy/migration.py,sha256=VNPXd-8i3ib5Cqq43uAQegwYiuWREZnHvmJCEmnErAo,3676
|
|
148
148
|
watcher/db/sqlalchemy/models.py,sha256=738iG47Amlb-QXpJhrNwpquQmjxIC-lqhOPaWa1ZTq8,10945
|
|
149
149
|
watcher/db/sqlalchemy/alembic/README.rst,sha256=iME9Yux4ZAcstexKFPsv_g4fpdaarKcvtscInoAvKTU,1942
|
|
150
150
|
watcher/db/sqlalchemy/alembic/env.py,sha256=D3nplgyG_dO0ikfBWhdDyBDZAYSY43kB-B88CcgeRMI,1769
|
|
151
151
|
watcher/db/sqlalchemy/alembic/script.py.mako,sha256=D8kFI44_9vBJZrAYSkZxDTX2-S5Y-oEetEd9BKlo9S8,412
|
|
152
152
|
watcher/db/sqlalchemy/alembic/versions/001_ocata.py,sha256=8ulT2iVUMn95fwLzeSrLfOYkwxaEOiBK26DVNMiUOM0,9500
|
|
153
|
-
watcher/db/sqlalchemy/alembic/versions/0f6042416884_add_apscheduler_jobs.py,sha256
|
|
153
|
+
watcher/db/sqlalchemy/alembic/versions/0f6042416884_add_apscheduler_jobs.py,sha256=El0qEzHBFJVUKffmBnj84OPRdrh2dfT036Z9LBGzQ1s,1145
|
|
154
154
|
watcher/db/sqlalchemy/alembic/versions/3cfc94cecf4e_add_name_for_audit.py,sha256=tCxWHYRSj9tOKG50WD8ok-lBmMavl_aPyoRKqL6dDnc,420
|
|
155
155
|
watcher/db/sqlalchemy/alembic/versions/4b16194c56bc_add_start_end_time.py,sha256=ZIjX__JLBpxGpsPEAvqDSjxmdNH0M9Fj_sLyQ1sOdV0,547
|
|
156
156
|
watcher/db/sqlalchemy/alembic/versions/52804f2498c4_add_hostname.py,sha256=W4iK-NtGb4Ku6jErsDYrUispfUGQLnGy9lHBje3DzP0,583
|
|
@@ -543,11 +543,11 @@ watcher/tests/objects/test_scoring_engine.py,sha256=y_crleFQFOUKrqT9tSI1NIP7eEMs
|
|
|
543
543
|
watcher/tests/objects/test_service.py,sha256=w8r6qgLJd0Vp3B774BInkWij4qUbMiykisIRSaxiqaA,5100
|
|
544
544
|
watcher/tests/objects/test_strategy.py,sha256=WoJYFQD0LU7vkUT2MMy1bx3S6eY458aTICjoGRiPccI,7364
|
|
545
545
|
watcher/tests/objects/utils.py,sha256=WtBFlXWIBRvl1keAjz1GtrkUWppil2pFIA-RngcqA5c,8058
|
|
546
|
-
python_watcher-
|
|
547
|
-
python_watcher-
|
|
548
|
-
python_watcher-
|
|
549
|
-
python_watcher-
|
|
550
|
-
python_watcher-
|
|
551
|
-
python_watcher-
|
|
552
|
-
python_watcher-
|
|
553
|
-
python_watcher-
|
|
546
|
+
python_watcher-13.0.0.dist-info/AUTHORS,sha256=8KbNuzGx0Rz8hCG-A51vIMwOP1sgVLnnjfkNo9B2R7I,7606
|
|
547
|
+
python_watcher-13.0.0.dist-info/LICENSE,sha256=XfKg2H1sVi8OoRxoisUlMqoo10TKvHmU_wU39ks7MyA,10143
|
|
548
|
+
python_watcher-13.0.0.dist-info/METADATA,sha256=3Hwq_SDSurkCVRSq59geMA6ohByFAYHboXP5K_E154s,3928
|
|
549
|
+
python_watcher-13.0.0.dist-info/WHEEL,sha256=g4nMs7d-Xl9-xC9XovUrsDHGXt-FT0E17Yqo92DEfvY,92
|
|
550
|
+
python_watcher-13.0.0.dist-info/entry_points.txt,sha256=FCdhj8D9hluy9jjmwnwmFVumvMeOCv6n_IoOCHF8-WU,4397
|
|
551
|
+
python_watcher-13.0.0.dist-info/pbr.json,sha256=_JP02CG21G2RH9wiiwMxaUNwaAiW-AzdgEUq2QlEvQk,47
|
|
552
|
+
python_watcher-13.0.0.dist-info/top_level.txt,sha256=O2B7Sbzshq5s-tZxb2a7VETvMDiJItSYieAiJ6Jm5yY,8
|
|
553
|
+
python_watcher-13.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"git_version": "a9dc3794", "is_release": true}
|
|
@@ -28,7 +28,7 @@ def upgrade():
|
|
|
28
28
|
|
|
29
29
|
op.create_table(
|
|
30
30
|
'apscheduler_jobs',
|
|
31
|
-
sa.Column('id', sa.Unicode(191
|
|
31
|
+
sa.Column('id', sa.Unicode(191),
|
|
32
32
|
nullable=False),
|
|
33
33
|
sa.Column('next_run_time', sa.Float(25), index=True),
|
|
34
34
|
sa.Column('job_state', sa.LargeBinary, nullable=False),
|
watcher/db/sqlalchemy/api.py
CHANGED
|
@@ -44,11 +44,7 @@ _FACADE = None
|
|
|
44
44
|
def _create_facade_lazily():
|
|
45
45
|
global _FACADE
|
|
46
46
|
if _FACADE is None:
|
|
47
|
-
|
|
48
|
-
# LegacyEngineFacade) asap since it's not compatible with SQLAlchemy
|
|
49
|
-
# 2.0.
|
|
50
|
-
_FACADE = db_session.EngineFacade.from_config(CONF,
|
|
51
|
-
autocommit=True)
|
|
47
|
+
_FACADE = db_session.EngineFacade.from_config(CONF)
|
|
52
48
|
return _FACADE
|
|
53
49
|
|
|
54
50
|
|
|
@@ -248,30 +244,36 @@ class Connection(api.BaseConnection):
|
|
|
248
244
|
for relationship in relationships:
|
|
249
245
|
if not relationship.uselist:
|
|
250
246
|
# We have a One-to-X relationship
|
|
251
|
-
query = query.options(joinedload(
|
|
247
|
+
query = query.options(joinedload(
|
|
248
|
+
getattr(model, relationship.key)))
|
|
252
249
|
return query
|
|
253
250
|
|
|
254
251
|
def _create(self, model, values):
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
252
|
+
session = get_session()
|
|
253
|
+
with session.begin():
|
|
254
|
+
obj = model()
|
|
255
|
+
cleaned_values = {k: v for k, v in values.items()
|
|
256
|
+
if k not in self._get_relationships(model)}
|
|
257
|
+
obj.update(cleaned_values)
|
|
258
|
+
obj.save(session=session)
|
|
259
|
+
session.commit()
|
|
260
260
|
return obj
|
|
261
261
|
|
|
262
262
|
def _get(self, context, model, fieldname, value, eager):
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
query =
|
|
263
|
+
session = get_session()
|
|
264
|
+
with session.begin():
|
|
265
|
+
query = model_query(model, session=session)
|
|
266
|
+
if eager:
|
|
267
|
+
query = self._set_eager_options(model, query)
|
|
266
268
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
269
|
+
query = query.filter(getattr(model, fieldname) == value)
|
|
270
|
+
if not context.show_deleted:
|
|
271
|
+
query = query.filter(model.deleted_at.is_(None))
|
|
270
272
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
273
|
+
try:
|
|
274
|
+
obj = query.one()
|
|
275
|
+
except exc.NoResultFound:
|
|
276
|
+
raise exception.ResourceNotFound(name=model.__name__, id=value)
|
|
275
277
|
|
|
276
278
|
return obj
|
|
277
279
|
|
|
@@ -22,6 +22,7 @@ from apscheduler.jobstores.base import ConflictingIdError
|
|
|
22
22
|
from apscheduler.jobstores import sqlalchemy
|
|
23
23
|
from apscheduler.util import datetime_to_utc_timestamp
|
|
24
24
|
from apscheduler.util import maybe_ref
|
|
25
|
+
from apscheduler.util import utc_timestamp_to_datetime
|
|
25
26
|
|
|
26
27
|
from watcher.common import context
|
|
27
28
|
from watcher.common import service
|
|
@@ -32,7 +33,7 @@ try:
|
|
|
32
33
|
except ImportError: # pragma: nocover
|
|
33
34
|
import pickle
|
|
34
35
|
|
|
35
|
-
from sqlalchemy import Table, MetaData, select, and_
|
|
36
|
+
from sqlalchemy import Table, MetaData, select, and_, null
|
|
36
37
|
from sqlalchemy.exc import IntegrityError
|
|
37
38
|
|
|
38
39
|
|
|
@@ -58,8 +59,7 @@ class WatcherJobStore(sqlalchemy.SQLAlchemyJobStore):
|
|
|
58
59
|
super(WatcherJobStore, self).__init__(url, engine, tablename,
|
|
59
60
|
metadata, pickle_protocol)
|
|
60
61
|
metadata = maybe_ref(metadata) or MetaData()
|
|
61
|
-
self.jobs_t = Table(tablename, metadata,
|
|
62
|
-
autoload_with=engine)
|
|
62
|
+
self.jobs_t = Table(tablename, metadata, autoload_with=engine)
|
|
63
63
|
service_ident = service.ServiceHeartbeat.get_service_name()
|
|
64
64
|
self.tag = tag or {'host': service_ident[0], 'name': service_ident[1]}
|
|
65
65
|
self.service_id = objects.Service.list(context=context.make_context(),
|
|
@@ -79,7 +79,8 @@ class WatcherJobStore(sqlalchemy.SQLAlchemyJobStore):
|
|
|
79
79
|
'tag': jsonutils.dumps(self.tag)
|
|
80
80
|
})
|
|
81
81
|
try:
|
|
82
|
-
self.engine.
|
|
82
|
+
with self.engine.begin() as conn:
|
|
83
|
+
conn.execute(insert)
|
|
83
84
|
except IntegrityError:
|
|
84
85
|
raise ConflictingIdError(job.id)
|
|
85
86
|
|
|
@@ -88,20 +89,36 @@ class WatcherJobStore(sqlalchemy.SQLAlchemyJobStore):
|
|
|
88
89
|
self._fix_paused_jobs_sorting(jobs)
|
|
89
90
|
return jobs
|
|
90
91
|
|
|
92
|
+
def get_next_run_time(self):
|
|
93
|
+
selectable = select(self.jobs_t.c.next_run_time).\
|
|
94
|
+
where(self.jobs_t.c.next_run_time != null()).\
|
|
95
|
+
order_by(self.jobs_t.c.next_run_time).limit(1)
|
|
96
|
+
with self.engine.begin() as connection:
|
|
97
|
+
# NOTE(danms): The apscheduler implementation of this gets a
|
|
98
|
+
# decimal.Decimal back from scalar() which causes
|
|
99
|
+
# utc_timestamp_to_datetime() to choke since it is expecting a
|
|
100
|
+
# python float. Assume this is SQLAlchemy 2.0 stuff, so just
|
|
101
|
+
# coerce to a float here.
|
|
102
|
+
next_run_time = connection.execute(selectable).scalar()
|
|
103
|
+
return utc_timestamp_to_datetime(float(next_run_time)
|
|
104
|
+
if next_run_time is not None
|
|
105
|
+
else None)
|
|
106
|
+
|
|
91
107
|
def _get_jobs(self, *conditions):
|
|
92
108
|
jobs = []
|
|
93
109
|
conditions += (self.jobs_t.c.service_id == self.service_id,)
|
|
94
110
|
selectable = select(
|
|
95
|
-
|
|
111
|
+
self.jobs_t.c.id, self.jobs_t.c.job_state, self.jobs_t.c.tag
|
|
96
112
|
).order_by(self.jobs_t.c.next_run_time).where(and_(*conditions))
|
|
97
113
|
failed_job_ids = set()
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
114
|
+
with self.engine.begin() as conn:
|
|
115
|
+
for row in conn.execute(selectable):
|
|
116
|
+
try:
|
|
117
|
+
jobs.append(self._reconstitute_job(row.job_state))
|
|
118
|
+
except Exception:
|
|
119
|
+
self._logger.exception(
|
|
120
|
+
'Unable to restore job "%s" -- removing it', row.id)
|
|
121
|
+
failed_job_ids.add(row.id)
|
|
105
122
|
|
|
106
123
|
# Remove all the jobs we failed to restore
|
|
107
124
|
if failed_job_ids:
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"git_version": "9d58a6d4", "is_release": true}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|