From a281595a682acffea1cd990dc197b72af8d3a917 Mon Sep 17 00:00:00 2001 From: Hugo Marcellin Date: Wed, 15 Apr 2026 10:51:48 +0200 Subject: [PATCH 1/9] Add unmount study script --- scripts/constant.py | 4 +- scripts/functions/studies/studies.py | 3 + scripts/unmount_unmodified_studies.py | 101 ++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 scripts/unmount_unmodified_studies.py diff --git a/scripts/constant.py b/scripts/constant.py index c719768..e7bc6bf 100644 --- a/scripts/constant.py +++ b/scripts/constant.py @@ -26,7 +26,7 @@ GRAFANA_API = "/api" # TODO add command parameter to set this DEV -DEV = False +DEV = True DEV_HOSTNAME = "172.17.0.1" # NOSONAR S1313 : this local IP is not excluded from this sonar issue @@ -96,6 +96,7 @@ DELETE_ROOT_NETWORKS = STUDY_SERVER_URL + "/supervision/root-networks" GET_DIRECTORY_ELEMENTS = DIRECTORY_SERVER_URL + "/supervision/elements" +GET_UNMODIFIED_DIRECTORY_ELEMENTS = DIRECTORY_SERVER_URL + "/supervision/elements/unmodified" GET_SUPERVISION_STUDIES = STUDY_SERVER_URL + "/supervision/studies" GET_DYNAMIC_MAPPING_FILTERS = DYNAMIC_MAPPING_SERVER_URL + "/supervision/filters" @@ -122,6 +123,7 @@ RECREATE_STUDY_INDICES = STUDY_SERVER_URL + "/supervision/studies/indices" DELETE_STUDY_INDEXED_EQUIPMENTS_BY_NETWORK_UUID = STUDY_SERVER_URL + "/supervision/studies/{networkUuid}/indexed-equipments-by-network-uuid" DELETE_STUDY_NODES_BUILDS = STUDY_SERVER_URL + "/supervision/studies/{studyUuid}/nodes/builds" +UNMOUNT_STUDY = STUDY_SERVER_URL + "/supervision/studies/{studyUuid}/unmount" GET_STUDIES_INDEXED_STUDIES_COUNT = STUDY_SERVER_URL + "/supervision/studies/indexation-count" GET_STUDIES_INDEXED_EQUIPMENTS_COUNT = STUDY_SERVER_URL + "/supervision/equipments/indexation-count" GET_STUDIES_INDEXED_TOMBSTONED_EQUIPMENTS_COUNT = STUDY_SERVER_URL + "/supervision/tombstoned-equipments/indexation-count" diff --git a/scripts/functions/studies/studies.py b/scripts/functions/studies/studies.py index 503cfe1..df2769a 100644 --- a/scripts/functions/studies/studies.py +++ b/scripts/functions/studies/studies.py @@ -36,4 +36,7 @@ def delete_indexed_equipments(networkUuid): def invalidate_nodes_builds(study_uuid): return requests.delete(constant.DELETE_STUDY_NODES_BUILDS.format(studyUuid = study_uuid)) + +def unmount_study(study_uuid): + return requests.delete(constant.UNMOUNT_STUDY.format(studyUuid = study_uuid)) diff --git a/scripts/unmount_unmodified_studies.py b/scripts/unmount_unmodified_studies.py new file mode 100644 index 0000000..5d625ee --- /dev/null +++ b/scripts/unmount_unmodified_studies.py @@ -0,0 +1,101 @@ +# +# Copyright (c) 2026, RTE (http://www.rte-france.com) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +import sys +import requests +import constant +from functions.studies.studies import unmount_study + +# +# Invalidates node builds and delete initial variant network for all studies that have not been modified since a given duration. +# +# Usage: +# python unmount_unmodified_studies.py [--dry-run] [--batch-size ] +# +# Arguments: +# duration ISO 8601 duration (e.g. P365D for 1 year, P30D for 30 days, PT24H for 24 hours) +# --dry-run Optional flag to only list affected studies without performing any invalidation +# --batch-size Optional maximum number of studies to process per execution +# +# Example: +# python unmount_unmodified_studies.py P365D +# python unmount_unmodified_studies.py P365D --batch-size 10 --dry-run +# + +# +# @author Hugo Marcellin +# + +def get_unmodified_studies(duration): + response = requests.get(constant.GET_UNMODIFIED_DIRECTORY_ELEMENTS, params={"elementType": "STUDY", "duration": duration}) + response.raise_for_status() + return response.json() + +def unmount_unmodified_studies(duration, dry_run=False, batch_size=None): + print(f"Fetching studies not modified since {duration}...") + studies = get_unmodified_studies(duration) + + if not studies: + print("No unmodified studies found.") + return + + print(f"Found {len(studies)} unmodified study/studies.") + + if batch_size is not None and batch_size < len(studies): + print(f"Batch size limit applied: processing {batch_size} out of {len(studies)} studies.") + studies = studies[:batch_size] + + print(f"Studies to process:") + for study in studies: + print(f" - {study['elementUuid']} | {study['elementName']} | last modified: {study['lastModificationDate']}") + + if dry_run: + print("\nDry run mode: no study will be unmounted.") + return + + if constant.DEV: + print(f"\nDEV={str(constant.DEV)} -> hostnames configured for a local execution (172.17.0.1:xxxx)") + + print("\nUnmounting studies...") + success_count = 0 + failure_count = 0 + for study in studies: + study_uuid = study["elementUuid"] + result = unmount_study(study_uuid) + if result.status_code == 200: + print(f" OK - {study_uuid}") + success_count += 1 + else: + print(f" FAILED - {study_uuid} (status: {result.status_code})") + failure_count += 1 + + print(f"\nDone. {success_count} succeeded, {failure_count} failed.") + + +if len(sys.argv) < 2: + print("Usage: python unmount_unmodified_studies.py [--dry-run] [--batch-size ]") + print("Example: python unmount_unmodified_studies.py P365D --batch-size 10 --dry-run") + sys.exit(1) + +duration_arg = sys.argv[1] +dry_run_arg = "--dry-run" in sys.argv + +batch_size_arg = None +if "--batch-size" in sys.argv: + batch_size_index = sys.argv.index("--batch-size") + if batch_size_index + 1 >= len(sys.argv): + print("Error: --batch-size requires a numeric value.") + sys.exit(1) + try: + batch_size_arg = int(sys.argv[batch_size_index + 1]) + if batch_size_arg <= 0: + raise ValueError + except ValueError: + print("Error: --batch-size must be a positive integer.") + sys.exit(1) + +unmount_unmodified_studies(duration_arg, dry_run=dry_run_arg, batch_size=batch_size_arg) \ No newline at end of file From 6ce72d2dd19b6f223a47fb9596bef333a52749e7 Mon Sep 17 00:00:00 2001 From: Hugo Marcellin Date: Wed, 15 Apr 2026 10:57:57 +0200 Subject: [PATCH 2/9] Rollback dev def --- scripts/constant.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/constant.py b/scripts/constant.py index e7bc6bf..4377255 100644 --- a/scripts/constant.py +++ b/scripts/constant.py @@ -26,7 +26,7 @@ GRAFANA_API = "/api" # TODO add command parameter to set this DEV -DEV = True +DEV = False DEV_HOSTNAME = "172.17.0.1" # NOSONAR S1313 : this local IP is not excluded from this sonar issue From ead6220f98d66b1ad889f16b001d798f2b148c30 Mon Sep 17 00:00:00 2001 From: Hugo Marcellin Date: Wed, 15 Apr 2026 10:58:41 +0200 Subject: [PATCH 3/9] Newline --- scripts/unmount_unmodified_studies.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/unmount_unmodified_studies.py b/scripts/unmount_unmodified_studies.py index 5d625ee..f65f029 100644 --- a/scripts/unmount_unmodified_studies.py +++ b/scripts/unmount_unmodified_studies.py @@ -98,4 +98,4 @@ def unmount_unmodified_studies(duration, dry_run=False, batch_size=None): print("Error: --batch-size must be a positive integer.") sys.exit(1) -unmount_unmodified_studies(duration_arg, dry_run=dry_run_arg, batch_size=batch_size_arg) \ No newline at end of file +unmount_unmodified_studies(duration_arg, dry_run=dry_run_arg, batch_size=batch_size_arg) From f7b6f4799c1d062434a7c9065f4cfabf4c073eb6 Mon Sep 17 00:00:00 2001 From: Hugo Marcellin Date: Thu, 16 Apr 2026 17:26:21 +0200 Subject: [PATCH 4/9] Rephrase comment --- scripts/unmount_unmodified_studies.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/unmount_unmodified_studies.py b/scripts/unmount_unmodified_studies.py index f65f029..51eee79 100644 --- a/scripts/unmount_unmodified_studies.py +++ b/scripts/unmount_unmodified_studies.py @@ -11,7 +11,7 @@ from functions.studies.studies import unmount_study # -# Invalidates node builds and delete initial variant network for all studies that have not been modified since a given duration. +# Invalidates built nodes and delete initial variant network for all studies that have not been modified since a given duration. # # Usage: # python unmount_unmodified_studies.py [--dry-run] [--batch-size ] From 4708639ca928f45b194b497d187bf80bf1d26dbc Mon Sep 17 00:00:00 2001 From: Hugo Marcellin Date: Mon, 20 Apr 2026 13:26:05 +0200 Subject: [PATCH 5/9] Rename batch-size to limit --- scripts/unmount_unmodified_studies.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/scripts/unmount_unmodified_studies.py b/scripts/unmount_unmodified_studies.py index 51eee79..d4aaf81 100644 --- a/scripts/unmount_unmodified_studies.py +++ b/scripts/unmount_unmodified_studies.py @@ -14,16 +14,16 @@ # Invalidates built nodes and delete initial variant network for all studies that have not been modified since a given duration. # # Usage: -# python unmount_unmodified_studies.py [--dry-run] [--batch-size ] +# python unmount_unmodified_studies.py [--dry-run] [--limit ] # # Arguments: # duration ISO 8601 duration (e.g. P365D for 1 year, P30D for 30 days, PT24H for 24 hours) # --dry-run Optional flag to only list affected studies without performing any invalidation -# --batch-size Optional maximum number of studies to process per execution +# --limit Optional maximum number of studies to process per execution # # Example: -# python unmount_unmodified_studies.py P365D -# python unmount_unmodified_studies.py P365D --batch-size 10 --dry-run +# python unmount_unmodified_studies.py P365D --dry-run +# python unmount_unmodified_studies.py P365D --limit 10 --dry-run # # @@ -77,25 +77,25 @@ def unmount_unmodified_studies(duration, dry_run=False, batch_size=None): if len(sys.argv) < 2: - print("Usage: python unmount_unmodified_studies.py [--dry-run] [--batch-size ]") - print("Example: python unmount_unmodified_studies.py P365D --batch-size 10 --dry-run") + print("Usage: python unmount_unmodified_studies.py [--dry-run] [--limit ]") + print("Example: python unmount_unmodified_studies.py P365D --limit 10 --dry-run") sys.exit(1) duration_arg = sys.argv[1] dry_run_arg = "--dry-run" in sys.argv batch_size_arg = None -if "--batch-size" in sys.argv: - batch_size_index = sys.argv.index("--batch-size") +if "--limit" in sys.argv: + batch_size_index = sys.argv.index("--limit") if batch_size_index + 1 >= len(sys.argv): - print("Error: --batch-size requires a numeric value.") + print("Error: --limit requires a numeric value.") sys.exit(1) try: batch_size_arg = int(sys.argv[batch_size_index + 1]) if batch_size_arg <= 0: raise ValueError except ValueError: - print("Error: --batch-size must be a positive integer.") + print("Error: --limit must be a positive integer.") sys.exit(1) unmount_unmodified_studies(duration_arg, dry_run=dry_run_arg, batch_size=batch_size_arg) From fea281d50df80f278cfa82116309955dae2f4d05 Mon Sep 17 00:00:00 2001 From: Hugo Marcellin Date: Mon, 20 Apr 2026 13:30:30 +0200 Subject: [PATCH 6/9] Reword log --- scripts/unmount_unmodified_studies.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/unmount_unmodified_studies.py b/scripts/unmount_unmodified_studies.py index d4aaf81..9697d21 100644 --- a/scripts/unmount_unmodified_studies.py +++ b/scripts/unmount_unmodified_studies.py @@ -49,7 +49,7 @@ def unmount_unmodified_studies(duration, dry_run=False, batch_size=None): print(f"Batch size limit applied: processing {batch_size} out of {len(studies)} studies.") studies = studies[:batch_size] - print(f"Studies to process:") + print("Selected studies:") for study in studies: print(f" - {study['elementUuid']} | {study['elementName']} | last modified: {study['lastModificationDate']}") From 3d519097a4086016b8f2cfef6d4cf245fd10d029 Mon Sep 17 00:00:00 2001 From: Hugo Marcellin Date: Mon, 20 Apr 2026 16:39:03 +0200 Subject: [PATCH 7/9] Replace batchsize term --- scripts/unmount_unmodified_studies.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/scripts/unmount_unmodified_studies.py b/scripts/unmount_unmodified_studies.py index 9697d21..b31166b 100644 --- a/scripts/unmount_unmodified_studies.py +++ b/scripts/unmount_unmodified_studies.py @@ -19,7 +19,7 @@ # Arguments: # duration ISO 8601 duration (e.g. P365D for 1 year, P30D for 30 days, PT24H for 24 hours) # --dry-run Optional flag to only list affected studies without performing any invalidation -# --limit Optional maximum number of studies to process per execution +# --limit Optional maximum number of studies to process # # Example: # python unmount_unmodified_studies.py P365D --dry-run @@ -35,7 +35,7 @@ def get_unmodified_studies(duration): response.raise_for_status() return response.json() -def unmount_unmodified_studies(duration, dry_run=False, batch_size=None): +def unmount_unmodified_studies(duration, dry_run=False, limit=None): print(f"Fetching studies not modified since {duration}...") studies = get_unmodified_studies(duration) @@ -45,9 +45,9 @@ def unmount_unmodified_studies(duration, dry_run=False, batch_size=None): print(f"Found {len(studies)} unmodified study/studies.") - if batch_size is not None and batch_size < len(studies): - print(f"Batch size limit applied: processing {batch_size} out of {len(studies)} studies.") - studies = studies[:batch_size] + if limit is not None and limit < len(studies): + print(f"Limit applied: processing {limit} out of {len(studies)} studies.") + studies = studies[:limit] print("Selected studies:") for study in studies: @@ -76,7 +76,7 @@ def unmount_unmodified_studies(duration, dry_run=False, batch_size=None): print(f"\nDone. {success_count} succeeded, {failure_count} failed.") -if len(sys.argv) < 2: +if len(sys.argv) < 1: print("Usage: python unmount_unmodified_studies.py [--dry-run] [--limit ]") print("Example: python unmount_unmodified_studies.py P365D --limit 10 --dry-run") sys.exit(1) @@ -84,18 +84,18 @@ def unmount_unmodified_studies(duration, dry_run=False, batch_size=None): duration_arg = sys.argv[1] dry_run_arg = "--dry-run" in sys.argv -batch_size_arg = None +limit_arg = None if "--limit" in sys.argv: - batch_size_index = sys.argv.index("--limit") - if batch_size_index + 1 >= len(sys.argv): + limit_index = sys.argv.index("--limit") + if limit_index + 1 >= len(sys.argv): print("Error: --limit requires a numeric value.") sys.exit(1) try: - batch_size_arg = int(sys.argv[batch_size_index + 1]) - if batch_size_arg <= 0: + limit_arg = int(sys.argv[limit_index + 1]) + if limit_arg <= 0: raise ValueError except ValueError: print("Error: --limit must be a positive integer.") sys.exit(1) -unmount_unmodified_studies(duration_arg, dry_run=dry_run_arg, batch_size=batch_size_arg) +unmount_unmodified_studies(duration_arg, dry_run=dry_run_arg, limit=limit_arg) From 40c4b05457c95aa4d778d27dcee54ca67b18c040 Mon Sep 17 00:00:00 2001 From: Hugo Marcellin Date: Wed, 22 Apr 2026 11:43:47 +0200 Subject: [PATCH 8/9] Restore error when no parameter --- scripts/unmount_unmodified_studies.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/scripts/unmount_unmodified_studies.py b/scripts/unmount_unmodified_studies.py index b31166b..13edc11 100644 --- a/scripts/unmount_unmodified_studies.py +++ b/scripts/unmount_unmodified_studies.py @@ -9,6 +9,7 @@ import requests import constant from functions.studies.studies import unmount_study +from tqdm import tqdm # # Invalidates built nodes and delete initial variant network for all studies that have not been modified since a given duration. @@ -36,6 +37,9 @@ def get_unmodified_studies(duration): return response.json() def unmount_unmodified_studies(duration, dry_run=False, limit=None): + if constant.DEV: + print(f"\nDEV={str(constant.DEV)} -> hostnames configured for a local execution (172.17.0.1:xxxx)") + print(f"Fetching studies not modified since {duration}...") studies = get_unmodified_studies(duration) @@ -57,26 +61,26 @@ def unmount_unmodified_studies(duration, dry_run=False, limit=None): print("\nDry run mode: no study will be unmounted.") return - if constant.DEV: - print(f"\nDEV={str(constant.DEV)} -> hostnames configured for a local execution (172.17.0.1:xxxx)") - print("\nUnmounting studies...") success_count = 0 failure_count = 0 - for study in studies: - study_uuid = study["elementUuid"] - result = unmount_study(study_uuid) - if result.status_code == 200: - print(f" OK - {study_uuid}") + for study in tqdm(studies): + try: + study_uuid = study["elementUuid"] + result = unmount_study(study_uuid) + result.raise_for_status() success_count += 1 - else: - print(f" FAILED - {study_uuid} (status: {result.status_code})") + except Exception as e: failure_count += 1 + tqdm.write(f" FAILED - {study_uuid} (error: {str(e)})") + if isinstance(e, requests.exceptions.RequestException) and e.response is not None: + tqdm.write("Response body: " + repr(e.response.text)) # repr for cheap escaping + tqdm.write("") # emtpy newline between errors for legibility print(f"\nDone. {success_count} succeeded, {failure_count} failed.") -if len(sys.argv) < 1: +if len(sys.argv) < 2: print("Usage: python unmount_unmodified_studies.py [--dry-run] [--limit ]") print("Example: python unmount_unmodified_studies.py P365D --limit 10 --dry-run") sys.exit(1) From 6c0c1bf01cb2768b36f4c33a40ed4da57f9f8626 Mon Sep 17 00:00:00 2001 From: Hugo Marcellin Date: Wed, 13 May 2026 10:52:53 +0200 Subject: [PATCH 9/9] change verb from unmoun to invalidate --- scripts/constant.py | 2 +- scripts/functions/studies/studies.py | 4 ++-- ...es.py => invalidate_unmodified_studies.py} | 20 +++++++++---------- 3 files changed, 13 insertions(+), 13 deletions(-) rename scripts/{unmount_unmodified_studies.py => invalidate_unmodified_studies.py} (81%) diff --git a/scripts/constant.py b/scripts/constant.py index 4377255..1eb3992 100644 --- a/scripts/constant.py +++ b/scripts/constant.py @@ -123,7 +123,7 @@ RECREATE_STUDY_INDICES = STUDY_SERVER_URL + "/supervision/studies/indices" DELETE_STUDY_INDEXED_EQUIPMENTS_BY_NETWORK_UUID = STUDY_SERVER_URL + "/supervision/studies/{networkUuid}/indexed-equipments-by-network-uuid" DELETE_STUDY_NODES_BUILDS = STUDY_SERVER_URL + "/supervision/studies/{studyUuid}/nodes/builds" -UNMOUNT_STUDY = STUDY_SERVER_URL + "/supervision/studies/{studyUuid}/unmount" +INVALIDATE_STUDY = STUDY_SERVER_URL + "/supervision/studies/{studyUuid}/invalidate" GET_STUDIES_INDEXED_STUDIES_COUNT = STUDY_SERVER_URL + "/supervision/studies/indexation-count" GET_STUDIES_INDEXED_EQUIPMENTS_COUNT = STUDY_SERVER_URL + "/supervision/equipments/indexation-count" GET_STUDIES_INDEXED_TOMBSTONED_EQUIPMENTS_COUNT = STUDY_SERVER_URL + "/supervision/tombstoned-equipments/indexation-count" diff --git a/scripts/functions/studies/studies.py b/scripts/functions/studies/studies.py index df2769a..624bc7f 100644 --- a/scripts/functions/studies/studies.py +++ b/scripts/functions/studies/studies.py @@ -37,6 +37,6 @@ def delete_indexed_equipments(networkUuid): def invalidate_nodes_builds(study_uuid): return requests.delete(constant.DELETE_STUDY_NODES_BUILDS.format(studyUuid = study_uuid)) -def unmount_study(study_uuid): - return requests.delete(constant.UNMOUNT_STUDY.format(studyUuid = study_uuid)) +def invalidate_study(study_uuid): + return requests.delete(constant.INVALIDATE_STUDY.format(studyUuid = study_uuid)) diff --git a/scripts/unmount_unmodified_studies.py b/scripts/invalidate_unmodified_studies.py similarity index 81% rename from scripts/unmount_unmodified_studies.py rename to scripts/invalidate_unmodified_studies.py index 13edc11..0593c91 100644 --- a/scripts/unmount_unmodified_studies.py +++ b/scripts/invalidate_unmodified_studies.py @@ -8,14 +8,14 @@ import sys import requests import constant -from functions.studies.studies import unmount_study +from functions.studies.studies import invalidate_study from tqdm import tqdm # # Invalidates built nodes and delete initial variant network for all studies that have not been modified since a given duration. # # Usage: -# python unmount_unmodified_studies.py [--dry-run] [--limit ] +# python invalidate_unmodified_studies.py [--dry-run] [--limit ] # # Arguments: # duration ISO 8601 duration (e.g. P365D for 1 year, P30D for 30 days, PT24H for 24 hours) @@ -23,8 +23,8 @@ # --limit Optional maximum number of studies to process # # Example: -# python unmount_unmodified_studies.py P365D --dry-run -# python unmount_unmodified_studies.py P365D --limit 10 --dry-run +# python invalidate_unmodified_studies.py P365D --dry-run +# python invalidate_unmodified_studies.py P365D --limit 10 --dry-run # # @@ -36,7 +36,7 @@ def get_unmodified_studies(duration): response.raise_for_status() return response.json() -def unmount_unmodified_studies(duration, dry_run=False, limit=None): +def invalidate_unmodified_studies(duration, dry_run=False, limit=None): if constant.DEV: print(f"\nDEV={str(constant.DEV)} -> hostnames configured for a local execution (172.17.0.1:xxxx)") @@ -58,7 +58,7 @@ def unmount_unmodified_studies(duration, dry_run=False, limit=None): print(f" - {study['elementUuid']} | {study['elementName']} | last modified: {study['lastModificationDate']}") if dry_run: - print("\nDry run mode: no study will be unmounted.") + print("\nDry run mode: no study will be invalidated.") return print("\nUnmounting studies...") @@ -67,7 +67,7 @@ def unmount_unmodified_studies(duration, dry_run=False, limit=None): for study in tqdm(studies): try: study_uuid = study["elementUuid"] - result = unmount_study(study_uuid) + result = invalidate_study(study_uuid) result.raise_for_status() success_count += 1 except Exception as e: @@ -81,8 +81,8 @@ def unmount_unmodified_studies(duration, dry_run=False, limit=None): if len(sys.argv) < 2: - print("Usage: python unmount_unmodified_studies.py [--dry-run] [--limit ]") - print("Example: python unmount_unmodified_studies.py P365D --limit 10 --dry-run") + print("Usage: python invalidate_unmodified_studies.py [--dry-run] [--limit ]") + print("Example: python invalidate_unmodified_studies.py P365D --limit 10 --dry-run") sys.exit(1) duration_arg = sys.argv[1] @@ -102,4 +102,4 @@ def unmount_unmodified_studies(duration, dry_run=False, limit=None): print("Error: --limit must be a positive integer.") sys.exit(1) -unmount_unmodified_studies(duration_arg, dry_run=dry_run_arg, limit=limit_arg) +invalidate_unmodified_studies(duration_arg, dry_run=dry_run_arg, limit=limit_arg)