fractal-server 2.14.0a14__py3-none-any.whl → 2.14.0a16__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.
- fractal_server/__init__.py +1 -1
- fractal_server/app/routes/api/v2/_aux_functions_history.py +8 -0
- fractal_server/app/routes/api/v2/history.py +3 -4
- fractal_server/app/runner/executors/local/runner.py +31 -5
- fractal_server/app/runner/executors/slurm_common/base_slurm_runner.py +29 -7
- fractal_server/app/runner/v2/db_tools.py +15 -1
- fractal_server/app/runner/v2/runner_functions.py +3 -4
- {fractal_server-2.14.0a14.dist-info → fractal_server-2.14.0a16.dist-info}/METADATA +1 -1
- {fractal_server-2.14.0a14.dist-info → fractal_server-2.14.0a16.dist-info}/RECORD +12 -12
- {fractal_server-2.14.0a14.dist-info → fractal_server-2.14.0a16.dist-info}/LICENSE +0 -0
- {fractal_server-2.14.0a14.dist-info → fractal_server-2.14.0a16.dist-info}/WHEEL +0 -0
- {fractal_server-2.14.0a14.dist-info → fractal_server-2.14.0a16.dist-info}/entry_points.txt +0 -0
fractal_server/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__VERSION__ = "2.14.
|
1
|
+
__VERSION__ = "2.14.0a16"
|
@@ -20,6 +20,10 @@ from fractal_server.app.routes.api.v2._aux_functions import (
|
|
20
20
|
from fractal_server.app.routes.api.v2._aux_functions import (
|
21
21
|
_get_workflowtask_or_404,
|
22
22
|
)
|
23
|
+
from fractal_server.logger import set_logger
|
24
|
+
|
25
|
+
|
26
|
+
logger = set_logger(__name__)
|
23
27
|
|
24
28
|
|
25
29
|
async def get_history_unit_or_404(
|
@@ -67,6 +71,10 @@ def read_log_file(
|
|
67
71
|
dataset_id: int,
|
68
72
|
):
|
69
73
|
if logfile is None or not Path(logfile).exists():
|
74
|
+
logger.debug(
|
75
|
+
f"Logs for task '{wftask.task.name}' in dataset "
|
76
|
+
f"{dataset_id} are not available ({logfile=})."
|
77
|
+
)
|
70
78
|
return (
|
71
79
|
f"Logs for task '{wftask.task.name}' in dataset "
|
72
80
|
f"{dataset_id} are not available."
|
@@ -84,11 +84,10 @@ async def get_workflow_tasks_statuses(
|
|
84
84
|
.limit(1)
|
85
85
|
)
|
86
86
|
latest_history_run = res.scalar_one_or_none()
|
87
|
-
logger.debug( # FIXME: remove
|
88
|
-
f"Given {dataset_id=} and {wftask.id}, "
|
89
|
-
f"found {latest_history_run=}."
|
90
|
-
)
|
91
87
|
if latest_history_run is None:
|
88
|
+
logger.debug(
|
89
|
+
f"No HistoryRun found for {dataset_id=} and {wftask.id=}."
|
90
|
+
)
|
92
91
|
response[wftask.id] = None
|
93
92
|
continue
|
94
93
|
response[wftask.id] = dict(
|
@@ -11,6 +11,9 @@ from fractal_server.app.runner.executors.base_runner import BaseRunner
|
|
11
11
|
from fractal_server.app.runner.task_files import MULTISUBMIT_PREFIX
|
12
12
|
from fractal_server.app.runner.task_files import SUBMIT_PREFIX
|
13
13
|
from fractal_server.app.runner.task_files import TaskFiles
|
14
|
+
from fractal_server.app.runner.v2.db_tools import (
|
15
|
+
update_logfile_of_history_unit,
|
16
|
+
)
|
14
17
|
from fractal_server.app.runner.v2.db_tools import update_status_of_history_unit
|
15
18
|
from fractal_server.app.schemas.v2 import HistoryUnitStatus
|
16
19
|
from fractal_server.logger import set_logger
|
@@ -69,7 +72,12 @@ class LocalRunner(BaseRunner):
|
|
69
72
|
workdir_local = task_files.wftask_subfolder_local
|
70
73
|
workdir_local.mkdir()
|
71
74
|
|
75
|
+
# Add prefix to task_files object
|
72
76
|
task_files.prefix = SUBMIT_PREFIX
|
77
|
+
update_logfile_of_history_unit(
|
78
|
+
history_unit_id=history_unit_id,
|
79
|
+
logfile=task_files.log_file_local,
|
80
|
+
)
|
73
81
|
|
74
82
|
# SUBMISSION PHASE
|
75
83
|
future = self.executor.submit(
|
@@ -155,17 +163,35 @@ class LocalRunner(BaseRunner):
|
|
155
163
|
active_futures: dict[int, Future] = {}
|
156
164
|
for ind_within_chunk, kwargs in enumerate(list_parameters_chunk):
|
157
165
|
positional_index = ind_chunk + ind_within_chunk
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
)
|
166
|
+
list_task_files[
|
167
|
+
positional_index
|
168
|
+
].prefix = f"{MULTISUBMIT_PREFIX}-{positional_index:06d}"
|
162
169
|
future = self.executor.submit(
|
163
170
|
func,
|
164
171
|
parameters=kwargs,
|
165
|
-
remote_files=
|
172
|
+
remote_files=list_task_files[
|
173
|
+
positional_index
|
174
|
+
].remote_files_dict,
|
166
175
|
)
|
167
176
|
active_futures[positional_index] = future
|
168
177
|
|
178
|
+
if task_type == "parallel":
|
179
|
+
# FIXME: replace loop with a `bulk_update_history_unit`
|
180
|
+
# function
|
181
|
+
update_logfile_of_history_unit(
|
182
|
+
history_unit_id=history_unit_ids[positional_index],
|
183
|
+
logfile=list_task_files[
|
184
|
+
positional_index
|
185
|
+
].log_file_local,
|
186
|
+
)
|
187
|
+
else:
|
188
|
+
logger.debug(
|
189
|
+
f"Unclear what logfile to associate to {task_type=} "
|
190
|
+
"within multisubmit (see issue #2382)."
|
191
|
+
)
|
192
|
+
# FIXME: Improve definition for compound tasks
|
193
|
+
pass
|
194
|
+
|
169
195
|
while active_futures:
|
170
196
|
# FIXME: add shutdown detection
|
171
197
|
# if file exists: cancel all futures, and raise
|
@@ -23,6 +23,9 @@ from fractal_server.app.runner.filenames import SHUTDOWN_FILENAME
|
|
23
23
|
from fractal_server.app.runner.task_files import MULTISUBMIT_PREFIX
|
24
24
|
from fractal_server.app.runner.task_files import SUBMIT_PREFIX
|
25
25
|
from fractal_server.app.runner.task_files import TaskFiles
|
26
|
+
from fractal_server.app.runner.v2.db_tools import (
|
27
|
+
update_logfile_of_history_unit,
|
28
|
+
)
|
26
29
|
from fractal_server.app.runner.v2.db_tools import update_status_of_history_unit
|
27
30
|
from fractal_server.app.schemas.v2 import HistoryUnitStatus
|
28
31
|
from fractal_server.config import get_settings
|
@@ -225,9 +228,9 @@ class BaseSlurmRunner(BaseRunner):
|
|
225
228
|
logger.info(script_lines)
|
226
229
|
|
227
230
|
# Always print output of `uname -n` and `pwd`
|
228
|
-
script_lines.append(
|
229
|
-
|
230
|
-
)
|
231
|
+
script_lines.append("Hostname: $(uname -n)\n")
|
232
|
+
script_lines.append("Current directory : $(pwd)\n")
|
233
|
+
script_lines.append('Start time: $(date + "%Y-%m-%dT%H:%M:%S%z")\n')
|
231
234
|
|
232
235
|
# Complete script preamble
|
233
236
|
script_lines.append("\n")
|
@@ -242,6 +245,7 @@ class BaseSlurmRunner(BaseRunner):
|
|
242
245
|
)
|
243
246
|
script_lines.append("wait\n")
|
244
247
|
script = "\n".join(script_lines)
|
248
|
+
script_lines.append('End time: $(date + "%Y-%m-%dT%H:%M:%S%z")\n')
|
245
249
|
|
246
250
|
# Write submission script
|
247
251
|
with open(slurm_job.slurm_submission_script_local, "w") as f:
|
@@ -400,6 +404,10 @@ class BaseSlurmRunner(BaseRunner):
|
|
400
404
|
|
401
405
|
# Add prefix to task_files object
|
402
406
|
task_files.prefix = SUBMIT_PREFIX
|
407
|
+
update_logfile_of_history_unit(
|
408
|
+
history_unit_id=history_unit_id,
|
409
|
+
logfile=task_files.log_file_local,
|
410
|
+
)
|
403
411
|
|
404
412
|
# Submission phase
|
405
413
|
slurm_job = SlurmJob(
|
@@ -549,18 +557,17 @@ class BaseSlurmRunner(BaseRunner):
|
|
549
557
|
tasks = []
|
550
558
|
for ind_chunk, parameters in enumerate(chunk):
|
551
559
|
index = (ind_batch * batch_size) + ind_chunk
|
552
|
-
|
553
|
-
current_task_files.prefix = prefix
|
560
|
+
list_task_files[index].prefix = prefix
|
554
561
|
tasks.append(
|
555
562
|
SlurmTask(
|
556
563
|
prefix=prefix,
|
557
564
|
index=index,
|
558
|
-
component=
|
565
|
+
component=list_task_files[index].component,
|
559
566
|
workdir_local=workdir_local,
|
560
567
|
workdir_remote=workdir_remote,
|
561
568
|
parameters=parameters,
|
562
569
|
zarr_url=parameters["zarr_url"],
|
563
|
-
task_files=
|
570
|
+
task_files=list_task_files[index],
|
564
571
|
),
|
565
572
|
)
|
566
573
|
|
@@ -575,6 +582,21 @@ class BaseSlurmRunner(BaseRunner):
|
|
575
582
|
slurm_job=slurm_job,
|
576
583
|
slurm_config=config,
|
577
584
|
)
|
585
|
+
if task_type == "parallel":
|
586
|
+
# FIXME: replace loop with a `bulk_update_history_unit` function
|
587
|
+
for ind, task_files in enumerate(list_task_files):
|
588
|
+
update_logfile_of_history_unit(
|
589
|
+
history_unit_id=history_unit_ids[ind],
|
590
|
+
logfile=task_files.log_file_local,
|
591
|
+
)
|
592
|
+
else:
|
593
|
+
logger.debug(
|
594
|
+
f"Unclear what logfile to associate to {task_type=} "
|
595
|
+
"within multisubmit (see issue #2382)."
|
596
|
+
)
|
597
|
+
# FIXME: Improve definition for compound tasks
|
598
|
+
pass
|
599
|
+
|
578
600
|
logger.info(f"END submission phase, {self.job_ids=}")
|
579
601
|
|
580
602
|
# FIXME: replace this sleep a more precise check
|
@@ -3,11 +3,14 @@ from typing import Any
|
|
3
3
|
from sqlalchemy.dialects.postgresql import insert as pg_insert
|
4
4
|
from sqlalchemy.orm import Session
|
5
5
|
|
6
|
+
from fractal_server.app.db import get_sync_db
|
6
7
|
from fractal_server.app.models.v2 import HistoryImageCache
|
7
8
|
from fractal_server.app.models.v2 import HistoryRun
|
8
9
|
from fractal_server.app.models.v2 import HistoryUnit
|
9
10
|
from fractal_server.app.schemas.v2 import HistoryUnitStatus
|
10
11
|
|
12
|
+
_CHUNK_SIZE = 2_000
|
13
|
+
|
11
14
|
|
12
15
|
def update_status_of_history_run(
|
13
16
|
*,
|
@@ -37,7 +40,18 @@ def update_status_of_history_unit(
|
|
37
40
|
db_sync.commit()
|
38
41
|
|
39
42
|
|
40
|
-
|
43
|
+
def update_logfile_of_history_unit(
|
44
|
+
*,
|
45
|
+
history_unit_id: int,
|
46
|
+
logfile: str,
|
47
|
+
) -> None:
|
48
|
+
with next(get_sync_db()) as db_sync:
|
49
|
+
unit = db_sync.get(HistoryUnit, history_unit_id)
|
50
|
+
if unit is None:
|
51
|
+
raise ValueError(f"HistoryUnit {history_unit_id} not found.")
|
52
|
+
unit.logfile = logfile
|
53
|
+
db_sync.merge(unit)
|
54
|
+
db_sync.commit()
|
41
55
|
|
42
56
|
|
43
57
|
def bulk_upsert_image_cache_fast(
|
@@ -172,7 +172,7 @@ def run_v2_task_non_parallel(
|
|
172
172
|
history_unit = HistoryUnit(
|
173
173
|
history_run_id=history_run_id,
|
174
174
|
status=HistoryUnitStatus.SUBMITTED,
|
175
|
-
logfile=
|
175
|
+
logfile=None,
|
176
176
|
zarr_urls=zarr_urls,
|
177
177
|
)
|
178
178
|
db.add(history_unit)
|
@@ -275,7 +275,7 @@ def run_v2_task_parallel(
|
|
275
275
|
HistoryUnit(
|
276
276
|
history_run_id=history_run_id,
|
277
277
|
status=HistoryUnitStatus.SUBMITTED,
|
278
|
-
logfile=
|
278
|
+
logfile=None,
|
279
279
|
zarr_urls=[image["zarr_url"]],
|
280
280
|
)
|
281
281
|
for ind, image in enumerate(images)
|
@@ -401,8 +401,7 @@ def run_v2_task_compound(
|
|
401
401
|
history_unit = HistoryUnit(
|
402
402
|
history_run_id=history_run_id,
|
403
403
|
status=HistoryUnitStatus.SUBMITTED,
|
404
|
-
|
405
|
-
logfile=task_files_init.log_file_local,
|
404
|
+
logfile=None,
|
406
405
|
zarr_urls=input_image_zarr_urls,
|
407
406
|
)
|
408
407
|
db.add(history_unit)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
fractal_server/__init__.py,sha256=
|
1
|
+
fractal_server/__init__.py,sha256=ewSoBgac6DlCJh5FbTCwJqfzkPFKTK2DqqhRuiv9G4k,26
|
2
2
|
fractal_server/__main__.py,sha256=rkM8xjY1KeS3l63irB8yCrlVobR-73uDapC4wvrIlxI,6957
|
3
3
|
fractal_server/alembic.ini,sha256=MWwi7GzjzawI9cCAK1LW7NxIBQDUqD12-ptJoq5JpP0,3153
|
4
4
|
fractal_server/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -32,11 +32,11 @@ fractal_server/app/routes/admin/v2/task_group_lifecycle.py,sha256=0e0ZJ_k75TVHaT
|
|
32
32
|
fractal_server/app/routes/api/__init__.py,sha256=B8l6PSAhR10iZqHEiyTat-_0tkeKdrCigIE6DJGP5b8,638
|
33
33
|
fractal_server/app/routes/api/v2/__init__.py,sha256=9o9zxTU2IJrC_JQ8GUMft3niiBZ39YLvODUeraiRRdQ,2465
|
34
34
|
fractal_server/app/routes/api/v2/_aux_functions.py,sha256=eE-TdEMI_UX3LBDUGwjG5NyUcihDVaHYlG15NlTJ9DI,12872
|
35
|
-
fractal_server/app/routes/api/v2/_aux_functions_history.py,sha256=
|
35
|
+
fractal_server/app/routes/api/v2/_aux_functions_history.py,sha256=ZlI6nwzB5r9AiY0C8TzJS_EQOTPKgkRYl3GpxFAu2bg,4430
|
36
36
|
fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py,sha256=qdXCb6IP8-qPEAxGZKljtjIqNzIAyRaAsQSRi5VqFHM,6773
|
37
37
|
fractal_server/app/routes/api/v2/_aux_functions_tasks.py,sha256=uhNSs-jcS7ndIUFKiOC1yrDiViw3uvKEXi9UL04BMks,11642
|
38
38
|
fractal_server/app/routes/api/v2/dataset.py,sha256=h5AhE0sdhQ20ZlIbEJsFnHIOUW0S1VHFpoflpBkVScs,8936
|
39
|
-
fractal_server/app/routes/api/v2/history.py,sha256=
|
39
|
+
fractal_server/app/routes/api/v2/history.py,sha256=BuXVCDUCIYG5YF49D4b_CsqQrx6uFH6WB4TgkrdS2zo,15926
|
40
40
|
fractal_server/app/routes/api/v2/images.py,sha256=BGpO94gVd8BTpCN6Mun2RXmjrPmfkIp73m8RN7uiGW4,8361
|
41
41
|
fractal_server/app/routes/api/v2/job.py,sha256=MU1sHIKk_89WrD0TD44d4ufzqnywot7On_W71KjyUbQ,6500
|
42
42
|
fractal_server/app/routes/api/v2/project.py,sha256=uAZgATiHcOvbnRX-vv1D3HoaEUvLUd7vzVmGcqOP8ZY,4602
|
@@ -73,13 +73,13 @@ fractal_server/app/runner/executors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQ
|
|
73
73
|
fractal_server/app/runner/executors/base_runner.py,sha256=s5aZLDPzC565FadaqFxrCLIlQzBn2D9iOpEjnBZROkk,5541
|
74
74
|
fractal_server/app/runner/executors/local/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
75
75
|
fractal_server/app/runner/executors/local/get_local_config.py,sha256=wbrIYuGOvABOStrE7jNrC4ULPhtBQ5Q7Y3aKm_icomg,3508
|
76
|
-
fractal_server/app/runner/executors/local/runner.py,sha256=
|
76
|
+
fractal_server/app/runner/executors/local/runner.py,sha256=Kv_ZTRARAg-lAhh-4tbSE1JcwukqGzgeQk0RAMLFgGk,8963
|
77
77
|
fractal_server/app/runner/executors/slurm_common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
78
78
|
fractal_server/app/runner/executors/slurm_common/_batching.py,sha256=ZY020JZlDS5mfpgpWTChQkyHU7iLE5kx2HVd57_C6XA,8850
|
79
79
|
fractal_server/app/runner/executors/slurm_common/_handle_exception_proxy.py,sha256=jU2N4vMafdcDPqVXwSApu4zxskCqhHmsXF3hBpOAAFA,577
|
80
80
|
fractal_server/app/runner/executors/slurm_common/_job_states.py,sha256=nuV-Zba38kDrRESOVB3gaGbrSPZc4q7YGichQaeqTW0,238
|
81
81
|
fractal_server/app/runner/executors/slurm_common/_slurm_config.py,sha256=fZaFUUXqDH0p3DndCFUpFqTqyD2tMVCuSYgYLAycpVw,15897
|
82
|
-
fractal_server/app/runner/executors/slurm_common/base_slurm_runner.py,sha256=
|
82
|
+
fractal_server/app/runner/executors/slurm_common/base_slurm_runner.py,sha256=9UpCV8CyqOeLzfEiJRxm4ODeJRDqQjE2QFx8Oi9ZjOA,26629
|
83
83
|
fractal_server/app/runner/executors/slurm_common/get_slurm_config.py,sha256=-fAX1DZMB5RZnyYanIJD72mWOJAPkh21jd4loDXKJw4,5994
|
84
84
|
fractal_server/app/runner/executors/slurm_common/remote.py,sha256=iXLu4d-bWzn7qmDaOjKFkcuaSHLjPESAMSLcg6c99fc,5852
|
85
85
|
fractal_server/app/runner/executors/slurm_common/slurm_job_task_models.py,sha256=YGgzTspkK9ItSMzwuYv_1tY7_1g89Qpeny5Auinxk1E,2708
|
@@ -99,11 +99,11 @@ fractal_server/app/runner/v2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
|
|
99
99
|
fractal_server/app/runner/v2/_local.py,sha256=DK8yagbvd6HHjcDVhUzTy0f7MURlTkQha-NM6OZKgJc,3044
|
100
100
|
fractal_server/app/runner/v2/_slurm_ssh.py,sha256=_bytOf8z9sdrhI03D6eqg-aQPnJ7V2-qnqpcHAYizns,3278
|
101
101
|
fractal_server/app/runner/v2/_slurm_sudo.py,sha256=DBCNxifXmMkpu71Wnk5u9-wKT7PV1WROQuY_4DYoZRI,2993
|
102
|
-
fractal_server/app/runner/v2/db_tools.py,sha256=
|
102
|
+
fractal_server/app/runner/v2/db_tools.py,sha256=tyLGY-g4ISZSJzk6ootEuHocdVwMg3taBL0oIivXV7M,2846
|
103
103
|
fractal_server/app/runner/v2/deduplicate_list.py,sha256=IVTE4abBU1bUprFTkxrTfYKnvkNTanWQ-KWh_etiT08,645
|
104
104
|
fractal_server/app/runner/v2/merge_outputs.py,sha256=D1L4Taieq9i71SPQyNc1kMokgHh-sV_MqF3bv7QMDBc,907
|
105
105
|
fractal_server/app/runner/v2/runner.py,sha256=SsKEZAsB8sPV8W3khTkAqaGdDwoTm_lav-fx6DdCwyA,15294
|
106
|
-
fractal_server/app/runner/v2/runner_functions.py,sha256=
|
106
|
+
fractal_server/app/runner/v2/runner_functions.py,sha256=5cK5O2rTrCsCxMTVN3iNPRwZ_891BC9_RMo64a8ZGYw,16338
|
107
107
|
fractal_server/app/runner/v2/runner_functions_low_level.py,sha256=9t1CHN3EyfsGRWfG257YPY5WjQ6zuztsw_KZrpEAFPo,3703
|
108
108
|
fractal_server/app/runner/v2/submit_workflow.py,sha256=EDUyUuIPwZHb2zm7SCRRoFsGq2cN-b5OKw6CYkZ8kWk,13048
|
109
109
|
fractal_server/app/runner/v2/task_interface.py,sha256=IXdQTI8rXFgXv1Ez0js4CjKFf3QwO2GCHRTuwiFtiTQ,2891
|
@@ -208,8 +208,8 @@ fractal_server/tasks/v2/utils_templates.py,sha256=Kc_nSzdlV6KIsO0CQSPs1w70zLyENP
|
|
208
208
|
fractal_server/urls.py,sha256=QjIKAC1a46bCdiPMu3AlpgFbcv6a4l3ABcd5xz190Og,471
|
209
209
|
fractal_server/utils.py,sha256=PMwrxWFxRTQRl1b9h-NRIbFGPKqpH_hXnkAT3NfZdpY,3571
|
210
210
|
fractal_server/zip_tools.py,sha256=GjDgo_sf6V_DDg6wWeBlZu5zypIxycn_l257p_YVKGc,4876
|
211
|
-
fractal_server-2.14.
|
212
|
-
fractal_server-2.14.
|
213
|
-
fractal_server-2.14.
|
214
|
-
fractal_server-2.14.
|
215
|
-
fractal_server-2.14.
|
211
|
+
fractal_server-2.14.0a16.dist-info/LICENSE,sha256=QKAharUuhxL58kSoLizKJeZE3mTCBnX6ucmz8W0lxlk,1576
|
212
|
+
fractal_server-2.14.0a16.dist-info/METADATA,sha256=cX3Og-LgceYk8wYfm6SlGSXr_5s-tDFI8VYJ48zPRWw,4563
|
213
|
+
fractal_server-2.14.0a16.dist-info/WHEEL,sha256=7dDg4QLnNKTvwIDR9Ac8jJaAmBC_owJrckbC0jjThyA,88
|
214
|
+
fractal_server-2.14.0a16.dist-info/entry_points.txt,sha256=8tV2kynvFkjnhbtDnxAqImL6HMVKsopgGfew0DOp5UY,58
|
215
|
+
fractal_server-2.14.0a16.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|