Skip to content

Commit 8dfd510

Browse files
authored
feat(core): v10 migrations (#3236)
1 parent 81ce86e commit 8dfd510

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+794
-332
lines changed

helm-chart/renku-core/values.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,15 @@ sentry:
9191
# versions is the list of different deployment that support different metadata versions.
9292
versions:
9393
latest:
94+
name: v10
95+
prefix: "10"
96+
nameOverride: ""
97+
fullnameOverride: ""
98+
image:
99+
repository: renku/renku-core
100+
tag: "v2.0.0"
101+
pullPolicy: IfNotPresent
102+
v9:
94103
name: v9
95104
prefix: "9"
96105
nameOverride: ""

renku/command/command_builder/database.py

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
import json
2222
import os
23-
from typing import TYPE_CHECKING, Optional
23+
from typing import Optional
2424

2525
from packaging.version import Version
2626

@@ -40,22 +40,19 @@
4040
from renku.infrastructure.gateway.project_gateway import ProjectGateway
4141
from renku.infrastructure.storage.factory import StorageFactory
4242

43-
if TYPE_CHECKING:
44-
from renku.domain_model.project import Project
45-
4643

4744
class DatabaseCommand(Command):
4845
"""Builder to get a database connection."""
4946

5047
PRE_ORDER = 4
5148
POST_ORDER = 5
5249

53-
def __init__(self, builder: Command, write: bool = False, path: str = None, create: bool = False) -> None:
50+
def __init__(self, builder: Command, write: bool = False, path: Optional[str] = None, create: bool = False) -> None:
5451
self._builder = builder
5552
self._write = write
5653
self._path = path
5754
self._create = create
58-
self.project: Optional["Project"] = None
55+
self.project_found: bool = False
5956

6057
def _injection_pre_hook(self, builder: Command, context: dict, *args, **kwargs) -> None:
6158
"""Create a Database singleton."""
@@ -80,8 +77,9 @@ def _injection_pre_hook(self, builder: Command, context: dict, *args, **kwargs)
8077
return
8178

8279
try:
83-
self.project = project_gateway.get_project()
84-
minimum_renku_version = Version(self.project.minimum_renku_version)
80+
project = project_gateway.get_project()
81+
minimum_renku_version = Version(project.minimum_renku_version)
82+
self.project_found = True
8583
except (KeyError, ImportError, ValueError):
8684
try:
8785
with open(project_context.database_path / "project", "r") as f:
@@ -102,13 +100,14 @@ def _injection_pre_hook(self, builder: Command, context: dict, *args, **kwargs)
102100
def _post_hook(self, builder: Command, context: dict, result: CommandResult, *args, **kwargs) -> None:
103101
from renku.domain_model.project import Project
104102

105-
if (
106-
self._write
107-
and self.project is not None
108-
and Version(self.project.minimum_renku_version) < Version(Project.minimum_renku_version)
109-
):
110-
# NOTE: update minimum renku version on write as migrations might happen on the fly
111-
self.project.minimum_renku_version = Project.minimum_renku_version
103+
if self._write and self.project_found:
104+
# NOTE: Fetch project again in case it was updated (the current reference would be put of date)
105+
project_gateway = ProjectGateway()
106+
project = project_gateway.get_project()
107+
108+
if Version(project.minimum_renku_version) < Version(Project.minimum_renku_version):
109+
# NOTE: update minimum renku version on write as migrations might happen on the fly
110+
project.minimum_renku_version = Project.minimum_renku_version
112111

113112
project_context.pop_context()
114113

renku/command/migrate.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,10 @@ def _template_migration_check():
9292

9393
try:
9494
project = project_context.project
95-
template_source = project.template_source
96-
template_ref = project.template_ref
97-
template_id = project.template_id
98-
except ValueError:
95+
template_source = project.template_metadata.template_source
96+
template_ref = project.template_metadata.template_ref
97+
template_id = project.template_metadata.template_id
98+
except (ValueError, AttributeError):
9999
project = None
100100
template_source = None
101101
template_ref = None
@@ -188,6 +188,10 @@ def _check_project():
188188
_ = project_context.project
189189
except ValueError:
190190
return MIGRATION_REQUIRED
191+
else:
192+
if hasattr(project_context.project, "template_source"):
193+
# NOTE: v10 migration not done
194+
return MIGRATION_REQUIRED
191195

192196
# NOTE: ``project.automated_update`` is deprecated and we always allow template update for a project
193197
status = AUTOMATED_TEMPLATE_UPDATE_SUPPORTED
@@ -213,7 +217,7 @@ def _check_immutable_template_files(paths: List[str]):
213217
Returns:
214218
List of immutable template files.
215219
"""
216-
immutable_template_files = project_context.project.immutable_template_files or []
220+
immutable_template_files = project_context.project.template_metadata.immutable_template_files or []
217221

218222
return [p for p in paths if str(p) in immutable_template_files]
219223

renku/command/rollback.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,14 +266,14 @@ def _get_modification_type_from_db(path: str) -> Optional[Tuple[str, str, str, d
266266
derived = database.get_by_id(db_object.derived_from)
267267
if db_object.name == derived.name:
268268
change_type = "modified"
269-
if db_object.invalidated_at:
269+
if db_object.date_removed:
270270
change_type = "restored"
271271

272272
return (
273273
f"Plan: {db_object.name}",
274274
change_type,
275275
f"plan_{db_object.name}",
276-
db_object.invalidated_at or db_object.date_created,
276+
db_object.date_removed or db_object.date_created,
277277
)
278278
elif isinstance(db_object, Dataset):
279279
change_type = "removed"

renku/command/schema/activity.py

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# limitations under the License.
1818
"""Activity JSON-LD schema."""
1919

20-
from marshmallow import EXCLUDE, pre_dump
20+
from marshmallow import EXCLUDE
2121

2222
from renku.command.schema.agent import PersonSchema, SoftwareAgentSchema
2323
from renku.command.schema.annotation import AnnotationSchema
@@ -35,29 +35,6 @@
3535
from renku.domain_model.provenance.parameter import ParameterValue
3636

3737

38-
class _ObjectWrapper:
39-
"""Object wrapper that allows temporarily overriding fields of immutable objects."""
40-
41-
def __init__(self, wrapped, **override):
42-
self.__wrapped = wrapped
43-
self.__override = override
44-
45-
def __getattr__(self, name):
46-
if name in self.__override:
47-
return self.__override[name]
48-
49-
return getattr(self.__wrapped, name)
50-
51-
52-
def _fix_id(obj):
53-
"""Fix ids under an activity that were wrong due to a bug."""
54-
55-
if not obj.id.startswith("/activities/") and not obj.id.startswith("/workflow-file-activity-collection/"):
56-
obj = _ObjectWrapper(obj, id=f"/activities/{obj.id}")
57-
58-
return obj
59-
60-
6138
class AssociationSchema(JsonLDSchema):
6239
"""Association schema."""
6340

@@ -72,11 +49,6 @@ class Meta:
7249
id = fields.Id()
7350
plan = Nested(prov.hadPlan, [PlanSchema, WorkflowFilePlanSchema, WorkflowFileCompositePlanSchema])
7451

75-
@pre_dump
76-
def _pre_dump(self, obj, **kwargs):
77-
"""Pre-dump hook."""
78-
return _fix_id(obj)
79-
8052

8153
class UsageSchema(JsonLDSchema):
8254
"""Usage schema."""
@@ -92,11 +64,6 @@ class Meta:
9264
# TODO: DatasetSchema, DatasetFileSchema
9365
entity = Nested(prov.entity, [EntitySchema, CollectionSchema])
9466

95-
@pre_dump
96-
def _pre_dump(self, obj, **kwargs):
97-
"""Pre-dump hook."""
98-
return _fix_id(obj)
99-
10067

10168
class GenerationSchema(JsonLDSchema):
10269
"""Generation schema."""
@@ -112,11 +79,6 @@ class Meta:
11279
# TODO: DatasetSchema, DatasetFileSchema
11380
entity = Nested(prov.qualifiedGeneration, [EntitySchema, CollectionSchema], reverse=True)
11481

115-
@pre_dump
116-
def _pre_dump(self, obj, **kwargs):
117-
"""Pre-dump hook."""
118-
return _fix_id(obj)
119-
12082

12183
class ParameterValueSchema(JsonLDSchema):
12284
"""ParameterValue schema."""
@@ -133,11 +95,6 @@ class Meta:
13395
parameter = fields.IRI(schema.valueReference, attribute="parameter_id")
13496
value = fields.Raw(schema.value)
13597

136-
@pre_dump
137-
def _pre_dump(self, obj, **kwargs):
138-
"""Pre-dump hook."""
139-
return _fix_id(obj)
140-
14198

14299
class ActivitySchema(JsonLDSchema):
143100
"""Activity schema."""
@@ -167,11 +124,6 @@ class Meta:
167124
started_at_time = fields.DateTime(prov.startedAtTime, add_value_types=True)
168125
usages = Nested(prov.qualifiedUsage, UsageSchema, many=True)
169126

170-
@pre_dump
171-
def _pre_dump(self, obj, **kwargs):
172-
"""Pre-dump hook."""
173-
return _fix_id(obj)
174-
175127

176128
class WorkflowFileActivityCollectionSchema(JsonLDSchema):
177129
"""WorkflowFileActivityCollection schema."""

renku/command/schema/composite_plan.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ class Meta:
4141
creators = Nested(schema.creator, PersonSchema, many=True)
4242
mappings = Nested(renku.hasMappings, [ParameterMappingSchema], many=True, load_default=None)
4343
date_created = fields.DateTime(schema.dateCreated, format="iso")
44-
invalidated_at = fields.DateTime(prov.invalidatedAtTime, format="iso")
44+
date_modified = fields.DateTime(schema.dateModified, format="iso")
45+
date_removed = fields.DateTime(prov.invalidatedAtTime, format="iso")
4546
keywords = fields.List(schema.keywords, fields.String(), load_default=None)
4647
name = fields.String(schema.name, load_default=None)
4748
derived_from = fields.IRI(prov.wasDerivedFrom, load_default=None)

renku/command/schema/dataset.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ class Meta:
148148
annotations = Nested(oa.hasTarget, AnnotationSchema, reverse=True, many=True)
149149
creators = Nested(schema.creator, PersonSchema, many=True)
150150
date_created = fields.DateTime(schema.dateCreated, load_default=None, format="iso", extra_formats=("%Y-%m-%d",))
151+
date_modified = fields.DateTime(schema.dateModified, load_default=None, format="iso", extra_formats=("%Y-%m-%d",))
151152
date_removed = fields.DateTime(prov.invalidatedAtTime, load_default=None, format="iso")
152153
date_published = fields.DateTime(
153154
schema.datePublished, load_default=None, format="%Y-%m-%d", extra_formats=("iso", "%Y-%m-%dT%H:%M:%S")

renku/command/schema/plan.py

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
# limitations under the License.
1818
"""Represent run templates."""
1919

20-
from datetime import timezone
21-
2220
import marshmallow
2321

2422
from renku.command.schema.agent import PersonSchema
@@ -46,7 +44,8 @@ class Meta:
4644
id = fields.Id()
4745
inputs = Nested(renku.hasInputs, CommandInputSchema, many=True, load_default=None)
4846
date_created = fields.DateTime(schema.dateCreated, format="iso")
49-
invalidated_at = fields.DateTime(prov.invalidatedAtTime, format="iso")
47+
date_modified = fields.DateTime(schema.dateModified, format="iso")
48+
date_removed = fields.DateTime(prov.invalidatedAtTime, format="iso")
5049
keywords = fields.List(schema.keywords, fields.String(), load_default=None)
5150
name = fields.String(schema.name, load_default=None)
5251
derived_from = fields.IRI(prov.wasDerivedFrom, load_default=None)
@@ -55,15 +54,3 @@ class Meta:
5554
parameters = Nested(renku.hasArguments, CommandParameterSchema, many=True, load_default=None)
5655
success_codes = fields.List(renku.successCodes, fields.Integer(), load_default=[0])
5756
annotations = Nested(oa.hasTarget, AnnotationSchema, reverse=True, many=True)
58-
59-
@marshmallow.pre_dump
60-
def _pre_dump(self, in_data, **kwargs):
61-
"""Fix data on dumping."""
62-
if in_data.invalidated_at is not None and in_data.invalidated_at.tzinfo is None:
63-
# NOTE: There was a bug that caused invalidated_at to be set without timezone (as UTC time)
64-
# so we patch in the timezone here
65-
in_data.unfreeze()
66-
in_data.invalidated_at = in_data.invalidated_at.replace(microsecond=0).astimezone(timezone.utc)
67-
in_data.freeze()
68-
69-
return in_data

renku/command/schema/project.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,25 @@ class Meta:
3737

3838
agent_version = StringList(schema.agent, load_default="pre-0.11.0")
3939
annotations = Nested(oa.hasTarget, AnnotationSchema, reverse=True, many=True)
40-
automated_update = fields.Boolean(renku.automatedTemplateUpdate, load_default=True)
4140
creator = Nested(schema.creator, PersonSchema, load_default=None)
4241
date_created = DateTimeList(schema.dateCreated, load_default=None, format="iso", extra_formats=("%Y-%m-%d",))
4342
description = fields.String(schema.description, load_default=None)
4443
id = fields.Id(load_default=None)
45-
immutable_template_files = fields.List(renku.immutableTemplateFiles, fields.String(), load_default=list())
44+
immutable_template_files = fields.List(
45+
renku.immutableTemplateFiles,
46+
fields.String(),
47+
load_default=list(),
48+
attribute="template_metadata.immutable_template_files",
49+
)
4650
name = fields.String(schema.name, load_default=None)
47-
template_id = fields.String(renku.templateId, load_default=None)
48-
template_metadata = fields.String(renku.templateMetadata, load_default=None)
49-
template_ref = fields.String(renku.templateReference, load_default=None)
50-
template_source = fields.String(renku.templateSource, load_default=None)
51-
template_version = fields.String(renku.templateVersion, load_default=None)
51+
template_id = fields.String(renku.templateId, load_default=None, attribute="template_metadata.template_id")
52+
template_metadata = fields.String(renku.templateMetadata, load_default=None, attribute="template_metadata.metadata")
53+
template_ref = fields.String(renku.templateReference, load_default=None, attribute="template_metadata.template_ref")
54+
template_source = fields.String(
55+
renku.templateSource, load_default=None, attribute="template_metadata.template_source"
56+
)
57+
template_version = fields.String(
58+
renku.templateVersion, load_default=None, attribute="template_metadata.template_version"
59+
)
5260
version = StringList(schema.schemaVersion, load_default="1")
5361
keywords = fields.List(schema.keywords, fields.String(), load_default=None)

renku/command/view_model/log.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,10 @@ def from_dataset(cls, dataset: "Dataset") -> "DatasetLogViewModel":
197197
descriptions.append("deleted")
198198
details.deleted = True
199199

200-
previous_dataset = None
200+
previous_dataset: Optional[Dataset] = None
201201

202202
if dataset.is_derivation():
203-
previous_dataset = dataset_gateway.get_by_id(dataset.derived_from.url_id) # type: ignore
203+
previous_dataset = dataset_gateway.get_by_id(dataset.derived_from.value) # type: ignore
204204

205205
current_files = {f for f in dataset.dataset_files if not f.date_removed}
206206
previous_files = set()
@@ -222,7 +222,7 @@ def from_dataset(cls, dataset: "Dataset") -> "DatasetLogViewModel":
222222

223223
descriptions.append(f"{len(new_files)} file(s) added")
224224
details.files_added = [str(f.entity.path) for f in new_files]
225-
details.modified = True
225+
details.modified = bool(previous_files)
226226

227227
if previous_files and {f.id for f in previous_files}.difference({f.id for f in current_files}):
228228
# NOTE: Files removed
@@ -277,8 +277,8 @@ def from_dataset(cls, dataset: "Dataset") -> "DatasetLogViewModel":
277277
details.keywords_removed = list(previous_keywords.difference(current_keywords))
278278
modified = True
279279

280-
current_images = set(dataset.images)
281-
previous_images = set(previous_dataset.images)
280+
current_images = set(dataset.images) if dataset.images else set()
281+
previous_images = set(previous_dataset.images) if previous_dataset.images else set()
282282

283283
if current_images != previous_images:
284284
details.images_changed_to = [i.content_url for i in current_images]

0 commit comments

Comments
 (0)