idmtools-platform-comps 0.0.0.dev0__py3-none-any.whl → 0.0.2__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.
- idmtools_platform_comps/__init__.py +25 -8
- idmtools_platform_comps/cli/__init__.py +4 -0
- idmtools_platform_comps/cli/cli_functions.py +50 -0
- idmtools_platform_comps/cli/comps.py +492 -0
- idmtools_platform_comps/comps_cli.py +48 -0
- idmtools_platform_comps/comps_operations/__init__.py +6 -0
- idmtools_platform_comps/comps_operations/asset_collection_operations.py +263 -0
- idmtools_platform_comps/comps_operations/experiment_operations.py +569 -0
- idmtools_platform_comps/comps_operations/simulation_operations.py +678 -0
- idmtools_platform_comps/comps_operations/suite_operations.py +228 -0
- idmtools_platform_comps/comps_operations/workflow_item_operations.py +269 -0
- idmtools_platform_comps/comps_platform.py +309 -0
- idmtools_platform_comps/plugin_info.py +168 -0
- idmtools_platform_comps/ssmt_operations/__init__.py +6 -0
- idmtools_platform_comps/ssmt_operations/simulation_operations.py +77 -0
- idmtools_platform_comps/ssmt_operations/workflow_item_operations.py +73 -0
- idmtools_platform_comps/ssmt_platform.py +44 -0
- idmtools_platform_comps/ssmt_work_items/__init__.py +4 -0
- idmtools_platform_comps/ssmt_work_items/comps_work_order_task.py +29 -0
- idmtools_platform_comps/ssmt_work_items/comps_workitems.py +113 -0
- idmtools_platform_comps/ssmt_work_items/icomps_workflowitem.py +71 -0
- idmtools_platform_comps/ssmt_work_items/work_order.py +54 -0
- idmtools_platform_comps/utils/__init__.py +4 -0
- idmtools_platform_comps/utils/assetize_output/__init__.py +4 -0
- idmtools_platform_comps/utils/assetize_output/assetize_output.py +125 -0
- idmtools_platform_comps/utils/assetize_output/assetize_ssmt_script.py +144 -0
- idmtools_platform_comps/utils/base_singularity_work_order.json +6 -0
- idmtools_platform_comps/utils/download/__init__.py +4 -0
- idmtools_platform_comps/utils/download/download.py +178 -0
- idmtools_platform_comps/utils/download/download_ssmt.py +81 -0
- idmtools_platform_comps/utils/download_experiment.py +116 -0
- idmtools_platform_comps/utils/file_filter_workitem.py +519 -0
- idmtools_platform_comps/utils/general.py +358 -0
- idmtools_platform_comps/utils/linux_mounts.py +73 -0
- idmtools_platform_comps/utils/lookups.py +123 -0
- idmtools_platform_comps/utils/package_version.py +489 -0
- idmtools_platform_comps/utils/python_requirements_ac/__init__.py +4 -0
- idmtools_platform_comps/utils/python_requirements_ac/create_asset_collection.py +155 -0
- idmtools_platform_comps/utils/python_requirements_ac/install_requirements.py +109 -0
- idmtools_platform_comps/utils/python_requirements_ac/requirements_to_asset_collection.py +374 -0
- idmtools_platform_comps/utils/python_version.py +40 -0
- idmtools_platform_comps/utils/scheduling.py +154 -0
- idmtools_platform_comps/utils/singularity_build.py +491 -0
- idmtools_platform_comps/utils/spatial_output.py +76 -0
- idmtools_platform_comps/utils/ssmt_utils/__init__.py +6 -0
- idmtools_platform_comps/utils/ssmt_utils/common.py +70 -0
- idmtools_platform_comps/utils/ssmt_utils/file_filter.py +568 -0
- idmtools_platform_comps/utils/sweeping.py +162 -0
- idmtools_platform_comps-0.0.2.dist-info/METADATA +100 -0
- idmtools_platform_comps-0.0.2.dist-info/RECORD +62 -0
- idmtools_platform_comps-0.0.2.dist-info/entry_points.txt +9 -0
- idmtools_platform_comps-0.0.2.dist-info/licenses/LICENSE.TXT +3 -0
- {idmtools_platform_comps-0.0.0.dev0.dist-info → idmtools_platform_comps-0.0.2.dist-info}/top_level.txt +1 -0
- ssmt_image/Dockerfile +52 -0
- ssmt_image/Makefile +21 -0
- ssmt_image/__init__.py +6 -0
- ssmt_image/bootstrap.sh +30 -0
- ssmt_image/build_docker_image.py +161 -0
- ssmt_image/pip.conf +3 -0
- ssmt_image/push_docker_image.py +49 -0
- ssmt_image/requirements.txt +9 -0
- idmtools_platform_comps-0.0.0.dev0.dist-info/METADATA +0 -41
- idmtools_platform_comps-0.0.0.dev0.dist-info/RECORD +0 -5
- {idmtools_platform_comps-0.0.0.dev0.dist-info → idmtools_platform_comps-0.0.2.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"""
|
|
2
|
+
idmtools utility.
|
|
3
|
+
|
|
4
|
+
Copyright 2025, Gates Foundation. All rights reserved.
|
|
5
|
+
"""
|
|
6
|
+
import numpy as np
|
|
7
|
+
from typing import Dict, Any, List
|
|
8
|
+
from idmtools.entities.simulation import Simulation
|
|
9
|
+
from logging import getLogger, DEBUG
|
|
10
|
+
|
|
11
|
+
logger = getLogger()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
##################################################
|
|
15
|
+
# Sweeping utility functions
|
|
16
|
+
##################################################
|
|
17
|
+
def set_param(simulation: Simulation, param: str, value: Any) -> Dict[str, Any]:
|
|
18
|
+
"""
|
|
19
|
+
Set a specific parameter value on the simulation task config.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
simulation (Simulation): idmtools Simulation object.
|
|
23
|
+
param (str): Name of the parameter to modify.
|
|
24
|
+
value (Any): New value to set.
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
Dict[str, Any]: A dictionary containing the parameter name and value.
|
|
28
|
+
"""
|
|
29
|
+
try:
|
|
30
|
+
return simulation.task.set_parameter(param, value)
|
|
31
|
+
except ValueError:
|
|
32
|
+
if "parameters" in simulation.task.config:
|
|
33
|
+
config = simulation.task.config.parameters
|
|
34
|
+
else:
|
|
35
|
+
config = simulation.task.config
|
|
36
|
+
|
|
37
|
+
config[param] = value
|
|
38
|
+
return {param: value}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def sweep_functions(simulation: Simulation, func_list: List) -> Dict[str, Any]:
|
|
42
|
+
"""
|
|
43
|
+
Apply a list of sweep functions to a simulation.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
simulation (Simulation): The simulation to update.
|
|
47
|
+
func_list (List[Callable]): List of functions that apply sweeps to the simulation.
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
Dict[str, Any]: A dictionary of aggregated metadata from each sweep function.
|
|
51
|
+
"""
|
|
52
|
+
tags_updated = {}
|
|
53
|
+
for func in func_list:
|
|
54
|
+
tags = func(simulation)
|
|
55
|
+
if tags:
|
|
56
|
+
tags_updated.update(tags)
|
|
57
|
+
return tags_updated
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class ItvFn:
|
|
61
|
+
"""
|
|
62
|
+
Sweeping utility for modifying interventions (campaign layer) during sweeps.
|
|
63
|
+
|
|
64
|
+
Requirements:
|
|
65
|
+
- func must accept an emod-api campaign object as its first argument.
|
|
66
|
+
- func must return a dictionary of metadata (i.e: tags).
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
Dict[str, Any]: Metadata returned by the intervention function, with numpy types cast to Python types.
|
|
70
|
+
"""
|
|
71
|
+
def __init__(self, func, *args, **kwargs): # noqa: D107
|
|
72
|
+
self.func = func
|
|
73
|
+
self.args = args
|
|
74
|
+
self.kwargs = kwargs
|
|
75
|
+
|
|
76
|
+
def __call__(self, simulation: Simulation): # noqa: D102
|
|
77
|
+
import emod_api.campaign as campaign
|
|
78
|
+
campaign.reset()
|
|
79
|
+
|
|
80
|
+
matadata = self.func(campaign, *self.args, **self.kwargs)
|
|
81
|
+
|
|
82
|
+
# Add new campaign events
|
|
83
|
+
events = campaign.campaign_dict["Events"]
|
|
84
|
+
simulation.task.campaign.add_events(events)
|
|
85
|
+
|
|
86
|
+
# Handle adhoc (custom) individual events
|
|
87
|
+
adhoc_events = campaign.get_adhocs()
|
|
88
|
+
if len(adhoc_events) > 0:
|
|
89
|
+
if logger.isEnabledFor(DEBUG):
|
|
90
|
+
logger.debug("Found adhoc events in campaign. Needs some special processing behind the scenes.")
|
|
91
|
+
if "Custom_Individual_Events" in simulation.task.config.parameters:
|
|
92
|
+
ev_exist = set(simulation.task.config.parameters.Custom_Individual_Events)
|
|
93
|
+
ev_addhoc = set(adhoc_events.keys())
|
|
94
|
+
simulation.task.config.parameters.Custom_Individual_Events = list(ev_exist.union(ev_addhoc))
|
|
95
|
+
else:
|
|
96
|
+
simulation.task.config.parameters.Report_Event_Recorder_Events.extend(list(set(adhoc_events.keys())))
|
|
97
|
+
|
|
98
|
+
# Convert numpy types
|
|
99
|
+
if matadata:
|
|
100
|
+
for k, v in matadata.items():
|
|
101
|
+
if isinstance(v, (np.int64, np.float64, np.float32, np.uint32, np.int16, np.int32)):
|
|
102
|
+
matadata[k] = v.item()
|
|
103
|
+
|
|
104
|
+
return matadata
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class CfgFn:
|
|
108
|
+
"""
|
|
109
|
+
Sweeping utility for modifying simulation configuration parameters.
|
|
110
|
+
|
|
111
|
+
Requirements:
|
|
112
|
+
- func must accept simulation.task.config as the first parameter.
|
|
113
|
+
- func must return a dictionary for tagging.
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
Dict[str, Any]: Metadata dictionary with Python-native types.
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
def __init__(self, func, *args, **kwargs): # noqa: D107
|
|
120
|
+
self.func = func
|
|
121
|
+
self.args = args
|
|
122
|
+
self.kwargs = kwargs
|
|
123
|
+
|
|
124
|
+
def __call__(self, simulation: Simulation): # noqa: D102
|
|
125
|
+
matadata = self.func(simulation.task.config, *self.args, **self.kwargs)
|
|
126
|
+
|
|
127
|
+
# Make sure we cast numpy types into normal system types
|
|
128
|
+
if matadata:
|
|
129
|
+
for k, v in matadata.items():
|
|
130
|
+
if isinstance(v, (np.int64, np.float64, np.float32, np.uint32, np.int16, np.int32)):
|
|
131
|
+
matadata[k] = v.item()
|
|
132
|
+
|
|
133
|
+
return matadata
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class SwpFn:
|
|
137
|
+
"""
|
|
138
|
+
Sweeping utility for modifying task-level elements (e.g., reports, demographics, climate).
|
|
139
|
+
|
|
140
|
+
Requirements:
|
|
141
|
+
- func must accept simulation.task as the first parameter.
|
|
142
|
+
- func must return a metadata dictionary (tags).
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
Dict[str, Any]: Metadata with numpy types cast to Python-native types.
|
|
146
|
+
"""
|
|
147
|
+
|
|
148
|
+
def __init__(self, func, *args, **kwargs): # noqa: D107
|
|
149
|
+
self.func = func
|
|
150
|
+
self.args = args
|
|
151
|
+
self.kwargs = kwargs
|
|
152
|
+
|
|
153
|
+
def __call__(self, simulation: Simulation): # noqa: D102
|
|
154
|
+
matadata = self.func(simulation.task, *self.args, **self.kwargs)
|
|
155
|
+
|
|
156
|
+
# Make sure we cast numpy types into normal system types
|
|
157
|
+
if matadata:
|
|
158
|
+
for k, v in matadata.items():
|
|
159
|
+
if isinstance(v, (np.int64, np.float64, np.float32, np.uint32, np.int16, np.int32)):
|
|
160
|
+
matadata[k] = v.item()
|
|
161
|
+
|
|
162
|
+
return matadata
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: idmtools_platform_comps
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: Comps platform for IDM-Tools
|
|
5
|
+
Author-email: Zhaowei Du <zdu@idmod.org>, Sharon Chen <shchen@idmod.org>, Clinton Collins <ccollins@idmod.org>, Benoit Raybaud <braybaud@idmod.org>, Clark Kirkman IV <ckirkman@idmod.org>, Ye Chen <yechen@idmod.org>, Mary Fisher <mafisher@idmod.org>, Mandy Izzo <mizzo@idmod.org>, Jen Schripsema <jschripsema@idmod.org>, Ross Carter <rcarter@idmod.org>
|
|
6
|
+
Project-URL: Homepage, https://github.com/InstituteforDiseaseModeling/idmtools
|
|
7
|
+
Keywords: modeling,IDM
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Requires-Python: >=3.8
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE.TXT
|
|
16
|
+
Requires-Dist: idmtools<1.0.0,>=0.0.0
|
|
17
|
+
Requires-Dist: pyCOMPS~=2.11
|
|
18
|
+
Requires-Dist: natsort~=8.4.0
|
|
19
|
+
Provides-Extra: test
|
|
20
|
+
Requires-Dist: idmtools[test]; extra == "test"
|
|
21
|
+
Requires-Dist: idmtools_test; extra == "test"
|
|
22
|
+
Requires-Dist: idmtools_models; extra == "test"
|
|
23
|
+
Provides-Extra: packaging
|
|
24
|
+
Requires-Dist: flake8; extra == "packaging"
|
|
25
|
+
Requires-Dist: coverage; extra == "packaging"
|
|
26
|
+
Requires-Dist: bump2version; extra == "packaging"
|
|
27
|
+
Requires-Dist: twine; extra == "packaging"
|
|
28
|
+
Requires-Dist: natsort; extra == "packaging"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+

|
|
32
|
+
|
|
33
|
+
# idmtools-platform-comps
|
|
34
|
+
|
|
35
|
+
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
|
36
|
+
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
|
37
|
+
**Table of Contents**
|
|
38
|
+
|
|
39
|
+
- [Installing](#installing)
|
|
40
|
+
- [Development Tips](#development-tips)
|
|
41
|
+
- [Building SSMT Docker Image](#building-ssmt-docker-image)
|
|
42
|
+
- [Choose SSMT Docker Image to use in test/script](#choose-ssmt-docker-image-to-use-in-testscript)
|
|
43
|
+
|
|
44
|
+
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
|
45
|
+
|
|
46
|
+
## Installing
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install idmtools-platform-comps --index-url=https://packages.idmod.org/api/pypi/pypi-production/simple
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
# Development Tips
|
|
53
|
+
|
|
54
|
+
There is a Makefile file available for most common development tasks. Here is a list of commands
|
|
55
|
+
```bash
|
|
56
|
+
clean - Clean up temproary files
|
|
57
|
+
lint - Lint package and tests
|
|
58
|
+
test - Run All tests
|
|
59
|
+
coverage - Run tests and generate coverage report that is shown in browser
|
|
60
|
+
```
|
|
61
|
+
On Windows, you can use `pymake` instead of `make`
|
|
62
|
+
|
|
63
|
+
# Building SSMT Docker Image
|
|
64
|
+
|
|
65
|
+
To build the SSMT Docker image, follow these steps
|
|
66
|
+
|
|
67
|
+
1. ```bash
|
|
68
|
+
docker login docker-production.packages.idmod.org
|
|
69
|
+
```
|
|
70
|
+
2. ```bash
|
|
71
|
+
make ssmt-image
|
|
72
|
+
```
|
|
73
|
+
3. When prompted, enter your idm username and password
|
|
74
|
+
|
|
75
|
+
# Choose SSMT Docker Image to use in test/script
|
|
76
|
+
|
|
77
|
+
There are three ways to choose which ssmt docker image to use in your script:
|
|
78
|
+
|
|
79
|
+
1. specify docker_image in SSMTWorkItem creation, for example,
|
|
80
|
+
```bash
|
|
81
|
+
wi = SSMTWorkItem(name=wi_name, command=command, docker_image='my_test_ssmt_docker_image')
|
|
82
|
+
```
|
|
83
|
+
2. define docker_image in your idmtools.ini, for example:
|
|
84
|
+
```bash
|
|
85
|
+
[COMPS2]
|
|
86
|
+
type = COMPS
|
|
87
|
+
endpoint = https://comps.idmod.org
|
|
88
|
+
environment = Calculon
|
|
89
|
+
......
|
|
90
|
+
docker_image = my_test_ssmt_docker_image
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
3. if not above two cases, idomtools system will determine the default ssmt docker image from platform for you:
|
|
94
|
+
|
|
95
|
+
if endpoint = https://comps.idmod.org, it will use production docker image
|
|
96
|
+
|
|
97
|
+
for all other cases, it will use the staging docker image
|
|
98
|
+
|
|
99
|
+
Note: if user overrode docker image in wi (case #1) and also defined docker image in idmtools.ini (case #2),
|
|
100
|
+
it will take #1 as higher priority
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
idmtools_platform_comps/__init__.py,sha256=q761fnOdJ5dHMHpppTworPXdxYXPL8F05yBSCYEbtn0,829
|
|
2
|
+
idmtools_platform_comps/comps_cli.py,sha256=WdeC7Z1-J1-l5FKu0g5SYlYjQQhOTtrPIP-UDGYRrag,1688
|
|
3
|
+
idmtools_platform_comps/comps_platform.py,sha256=ZMyEzDXnGi4-8Tewam0a0jyDL46P4C0DLZ_oLQ8uMQ4,14762
|
|
4
|
+
idmtools_platform_comps/plugin_info.py,sha256=NBKl8cPNzxy185x5XgVbm92Yl8DZl7pL_OWWHutCQds,5751
|
|
5
|
+
idmtools_platform_comps/ssmt_platform.py,sha256=Yp8FTT8bKjmnRC7Cdz5PmOBvGvy5Oif27hSSlAtlxdc,1808
|
|
6
|
+
idmtools_platform_comps/cli/__init__.py,sha256=YSMg0oRXQjJME5sfJqZ4AK2LTtcK4vng8IIQfztNNhQ,105
|
|
7
|
+
idmtools_platform_comps/cli/cli_functions.py,sha256=ajLR0OmRFvSImAn7tBXy63ul5nt4w5VzztQ8mmIC95k,1561
|
|
8
|
+
idmtools_platform_comps/cli/comps.py,sha256=GFIhCfq_IskHEP8VDKAbiCglRvW-J1mkYqw6KBZX1tM,25676
|
|
9
|
+
idmtools_platform_comps/comps_operations/__init__.py,sha256=nbpywJN29X4gFDmU__MbBAiSra03h0xMmL-HbSt0RIs,177
|
|
10
|
+
idmtools_platform_comps/comps_operations/asset_collection_operations.py,sha256=tx_O_CJoW8S04AWL9D6sY3KDd8Bo1aLWt5E2o943pXg,11555
|
|
11
|
+
idmtools_platform_comps/comps_operations/experiment_operations.py,sha256=kpM7bSKvBNnhmHNwcHpz2X5XuMFJVT45aMx4MIV0cms,23756
|
|
12
|
+
idmtools_platform_comps/comps_operations/simulation_operations.py,sha256=uBagWIBSqbWkxyJlkuxRPfPsQGy_PpdFnIPn-iLv2wk,29951
|
|
13
|
+
idmtools_platform_comps/comps_operations/suite_operations.py,sha256=KcjoK1rL6y3wPBU1PHfYBU20Y1Y1Iar5fzjknDh8sf8,7573
|
|
14
|
+
idmtools_platform_comps/comps_operations/workflow_item_operations.py,sha256=zMXjTYc3oNWDvFHv2v4UdIRfzpPTa56qWEjrjzkjgzE,9989
|
|
15
|
+
idmtools_platform_comps/ssmt_operations/__init__.py,sha256=cBNIFW7ml6eFxEMoagrNUAg5-zBpsYgI8O_WcRenITw,218
|
|
16
|
+
idmtools_platform_comps/ssmt_operations/simulation_operations.py,sha256=447SRVUiQMatCwSd5XLwb12ZOylkXU8-ZU-Mi00VJGg,2991
|
|
17
|
+
idmtools_platform_comps/ssmt_operations/workflow_item_operations.py,sha256=T-V__FTFFlGzrEvYVa5XSemI2dhECNx16SCdTXg1WjY,2801
|
|
18
|
+
idmtools_platform_comps/ssmt_work_items/__init__.py,sha256=0OknVYmNvKuidiudz3I8z8Kf8vtL5QF_vcoccqAODQM,104
|
|
19
|
+
idmtools_platform_comps/ssmt_work_items/comps_work_order_task.py,sha256=caGz5oFZkiDhSHBdn4XYkmFHWAPVK6BRybQ-9TrrYUM,873
|
|
20
|
+
idmtools_platform_comps/ssmt_work_items/comps_workitems.py,sha256=7nMsv-L4_A-ugSFM6qcM82fy3pYP8P95j-33BFupFwg,3717
|
|
21
|
+
idmtools_platform_comps/ssmt_work_items/icomps_workflowitem.py,sha256=yUpETmG4geXJAIrtVHh7mUFqSpdfYsjKnmtH-2c6qYs,1897
|
|
22
|
+
idmtools_platform_comps/ssmt_work_items/work_order.py,sha256=G6kcqZb-OLzykbNLtIDDFyS4fhiU-OPbgnmOnfmMImo,1653
|
|
23
|
+
idmtools_platform_comps/utils/__init__.py,sha256=eerSmYyuqPdwpt6aHUEsPjhNcYGaSfQOQdLJ-8rhBDo,100
|
|
24
|
+
idmtools_platform_comps/utils/base_singularity_work_order.json,sha256=YCrJSkhiX5igP_VYjMNlunUs0Y9jueWCPj5L5eGZYYA,87
|
|
25
|
+
idmtools_platform_comps/utils/download_experiment.py,sha256=5hkrYD90tMDjM9Vgw3YjNyCMe4qUt9LVUJCbRH0qMFw,3333
|
|
26
|
+
idmtools_platform_comps/utils/file_filter_workitem.py,sha256=0d1ApTZQGVP-9EaJhYB8h88yjZRZ1nACvz6rN5foxY4,21074
|
|
27
|
+
idmtools_platform_comps/utils/general.py,sha256=Xp8au0JSK_E5cIOMkQSJ0ppGMWhirxODoZVOWYlSe_o,12366
|
|
28
|
+
idmtools_platform_comps/utils/linux_mounts.py,sha256=xai-RUIm6dPnjYamgEjc4lYiJBpZqyupbSVNinB_XmQ,2605
|
|
29
|
+
idmtools_platform_comps/utils/lookups.py,sha256=PBMuRaENuJEYxYkd1PA7aFDBDIOM7IX2Xqi5sEc3OHY,4378
|
|
30
|
+
idmtools_platform_comps/utils/package_version.py,sha256=r1UyATqvMCOMKCbwHCUMniGHv8RJGrd68jc28Yt7UMo,16149
|
|
31
|
+
idmtools_platform_comps/utils/python_version.py,sha256=15DxlGjo4lrKm2w43dD2_Vf7p5oKfOoF9g8W7qp9zlI,1290
|
|
32
|
+
idmtools_platform_comps/utils/scheduling.py,sha256=-hkNSXtHzd1BT_InbGq5CUB-ChN0L1K6Bd9oai91N3g,6173
|
|
33
|
+
idmtools_platform_comps/utils/singularity_build.py,sha256=TzbabKEbsP6rlADF7hZ6C4TyOEVMP7bNKIi9FSTeoh8,20569
|
|
34
|
+
idmtools_platform_comps/utils/spatial_output.py,sha256=bNSwjb957D0L3BKo-wOPmTAg5lGMEVTIz6ypA12C6fQ,2334
|
|
35
|
+
idmtools_platform_comps/utils/sweeping.py,sha256=8GofrbofLrJu9POQNl09lNoZk1d6nWlPaIjgEaajcxw,5434
|
|
36
|
+
idmtools_platform_comps/utils/assetize_output/__init__.py,sha256=hRdtgRQ4EQNTXZQXJ4_Ym9dG7Bn49cCsum3JEdHa3pA,104
|
|
37
|
+
idmtools_platform_comps/utils/assetize_output/assetize_output.py,sha256=HhZCbdb29UFwhMYofupzsLPtt2bqE_oMHWZs17fztZM,5314
|
|
38
|
+
idmtools_platform_comps/utils/assetize_output/assetize_ssmt_script.py,sha256=nUSvFEFeuLLaXttM9NgguiLKtdjULCzYoAhfcd7IuN0,4844
|
|
39
|
+
idmtools_platform_comps/utils/download/__init__.py,sha256=y9lZ4H9k0MbHS70b02BUnpF4lSoTDKrjDnWM67nrpQU,106
|
|
40
|
+
idmtools_platform_comps/utils/download/download.py,sha256=VFJALnMJtUz39xRaqyLcXOz1gimwcn3iZE6vsB6oJPo,6871
|
|
41
|
+
idmtools_platform_comps/utils/download/download_ssmt.py,sha256=Iu2ggZlLbq5nBQi2Fh4dKjscqXK_tE_d-oLET3_FADU,3194
|
|
42
|
+
idmtools_platform_comps/utils/python_requirements_ac/__init__.py,sha256=5SB84oji6LJ9TD_c_WT8OXgvonDuGfSW6joe3PHQJec,117
|
|
43
|
+
idmtools_platform_comps/utils/python_requirements_ac/create_asset_collection.py,sha256=14xYbrfc5pew4hI0iTN_wb5wq0T3SUlbLbxri8WkQJY,5042
|
|
44
|
+
idmtools_platform_comps/utils/python_requirements_ac/install_requirements.py,sha256=0Oo1SEbBoC8EDvNwmWz1s2xp3w62zExGd0oEmJp6RmU,3515
|
|
45
|
+
idmtools_platform_comps/utils/python_requirements_ac/requirements_to_asset_collection.py,sha256=aMgmlgqcB0_eYe3bdhKyjgXhe2b2LWedOYowB6xZOOk,13632
|
|
46
|
+
idmtools_platform_comps/utils/ssmt_utils/__init__.py,sha256=9p8SmJ5g21Tk2dOAkfc3Kh8MZ3uWEMWo-ysdk4Wllak,158
|
|
47
|
+
idmtools_platform_comps/utils/ssmt_utils/common.py,sha256=67-sGWOBnJaR31BE6SvtZ2ajFF57lc_jsmvH3eJ_wDY,2272
|
|
48
|
+
idmtools_platform_comps/utils/ssmt_utils/file_filter.py,sha256=Nx2_OF4kXDMgO48BhbIcglNJgUim-tdcZ7gsTJMCbfI,26810
|
|
49
|
+
idmtools_platform_comps-0.0.2.dist-info/licenses/LICENSE.TXT,sha256=l9S8Ydr_LcejxKoqK8191ZAOsmVX-nJLSPoLKZDUgcg,197
|
|
50
|
+
ssmt_image/Dockerfile,sha256=5cENyIiv8hnmmGHxEW1vCGgsJsQ2T-sq4Nvdbjz3k_Q,1787
|
|
51
|
+
ssmt_image/Makefile,sha256=kq4BufedyACnD9Z96ypNXsuNI__UEhH73IILuSoOaOk,620
|
|
52
|
+
ssmt_image/__init__.py,sha256=tKN1Oxn8Y7VjaLoKeOviyb_MNrdyTru1NRkxaKWRyM8,130
|
|
53
|
+
ssmt_image/bootstrap.sh,sha256=V0psR_4rJ-sWcmsy-XDnNrbqkgpAXu1rrwVUlRpHgNQ,755
|
|
54
|
+
ssmt_image/build_docker_image.py,sha256=v1zlLTn8TU0HlClUGvmAdcUUMHa0vZcI2uvqK22cq4E,6671
|
|
55
|
+
ssmt_image/pip.conf,sha256=hKl-m_qBXwyQ3QU_lq5tber-7MVizUomo9Kxw5Snb-I,157
|
|
56
|
+
ssmt_image/push_docker_image.py,sha256=GshSewoKZAibWh32YKFWTv9nu78HSXJD6FOY1HcIVvE,1806
|
|
57
|
+
ssmt_image/requirements.txt,sha256=1jO8Nl0sU0fqOdVwIf0bXHK8DiVjRezbTKZUug4Bmn4,135
|
|
58
|
+
idmtools_platform_comps-0.0.2.dist-info/METADATA,sha256=dSWkDTi2ERgazHwdW9iNb2pXnMIlMS_8ozlJBPb1HTA,3793
|
|
59
|
+
idmtools_platform_comps-0.0.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
60
|
+
idmtools_platform_comps-0.0.2.dist-info/entry_points.txt,sha256=y9ye9nY5E2wjFygMgGnvW9pLyZG4a8FW_0vVjgyH06Q,354
|
|
61
|
+
idmtools_platform_comps-0.0.2.dist-info/top_level.txt,sha256=JGCUUIm6XvUKwv2sqP1HMROi7fMhZxD5q5uhiILd0C0,35
|
|
62
|
+
idmtools_platform_comps-0.0.2.dist-info/RECORD,,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
[console_scripts]
|
|
2
|
+
comps-cli = idmtools_platform_comps.cli.comps:comps
|
|
3
|
+
|
|
4
|
+
[idmtools_cli.cli_plugins]
|
|
5
|
+
comps_subcommand = idmtools_platform_comps.cli.comps:comps
|
|
6
|
+
|
|
7
|
+
[idmtools_platform]
|
|
8
|
+
idmtools_platform_comps = idmtools_platform_comps.plugin_info:COMPSPlatformSpecification
|
|
9
|
+
idmtools_platform_ssmt = idmtools_platform_comps.plugin_info:SSMTPlatformSpecification
|
ssmt_image/Dockerfile
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
FROM ubuntu:20.04
|
|
2
|
+
|
|
3
|
+
# Install dependencies
|
|
4
|
+
RUN apt-get update
|
|
5
|
+
|
|
6
|
+
ENV PYTHONPATH=./Assets/:./Assets/site-packages/:.
|
|
7
|
+
# set the timezone - do this before installing python
|
|
8
|
+
RUN export DEBIAN_FRONTEND=noninteractive && \
|
|
9
|
+
apt-get update && \
|
|
10
|
+
apt-get install -y tzdata
|
|
11
|
+
RUN ln -fs /usr/share/zoneinfo/America/Los_Angeles /etc/localtime
|
|
12
|
+
RUN dpkg-reconfigure --frontend noninteractive tzdata
|
|
13
|
+
|
|
14
|
+
# install Python3
|
|
15
|
+
RUN apt-get install -y python3-pip
|
|
16
|
+
RUN apt-get install -y python3-dev
|
|
17
|
+
RUN pip install --upgrade pip setuptools
|
|
18
|
+
|
|
19
|
+
# r packages to support analysis in R
|
|
20
|
+
RUN apt-get install -y xz-utils llvm r-base \
|
|
21
|
+
# clean up temporary data
|
|
22
|
+
&& mkdir -p /root/.pip
|
|
23
|
+
|
|
24
|
+
# && apt-get clean && \ <--- We do this at the end of this file
|
|
25
|
+
# mkdir -p /root/.pip && \
|
|
26
|
+
# rm -rf /var/lib/apt/lists/* <--- We do this at the end of this file
|
|
27
|
+
|
|
28
|
+
# add requirements file
|
|
29
|
+
ADD requirements.txt /tmp/
|
|
30
|
+
# set default index to IDM Pip Prod(Caching and internal packages IDMTools may depend on like pyComps
|
|
31
|
+
ADD pip.conf /etc/pip.conf
|
|
32
|
+
|
|
33
|
+
COPY .depends/* /tmp/
|
|
34
|
+
|
|
35
|
+
RUN pip3 install -U pip && \
|
|
36
|
+
pip install pygit2
|
|
37
|
+
|
|
38
|
+
RUN bash -c "pip3 install /tmp/*.gz --index-url=https://packages.idmod.org/api/pypi/pypi-production/simple"
|
|
39
|
+
|
|
40
|
+
# make the PIP index configurable so we can build against staging, production, or a local PyPI server
|
|
41
|
+
ARG SSMT_VERSION
|
|
42
|
+
|
|
43
|
+
# Install the packages
|
|
44
|
+
RUN pip3 install --upgrade pip --index-url=https://pypi.python.org/simple && \
|
|
45
|
+
pip3 install dataclasses && \
|
|
46
|
+
pip3 install -r /tmp/requirements.txt && \
|
|
47
|
+
rm -rf /root/.cache
|
|
48
|
+
# To make this effective, we need to collapse this to one layer....... so don't do it for now
|
|
49
|
+
# remove stuff we needed for pip but don't want in our final image
|
|
50
|
+
# apt-get remove build-essential
|
|
51
|
+
|
|
52
|
+
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
|
ssmt_image/Makefile
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
.PHONY: help clean clean-all docker docker-release-staging
|
|
2
|
+
IPY=python -c
|
|
3
|
+
PY?=python
|
|
4
|
+
PDS=$(PY) ../../dev_scripts/
|
|
5
|
+
PDR=$(PDS)run.py
|
|
6
|
+
|
|
7
|
+
help:
|
|
8
|
+
help-from-makefile -f ./Makefile
|
|
9
|
+
|
|
10
|
+
clean-all: clean ## Deleting package info hides plugins so we only want to do that for packaging
|
|
11
|
+
$(CLDIR) --dir-patterns "**/*.egg-info/"
|
|
12
|
+
docker rmi idmtools_comps_ssmt_worker
|
|
13
|
+
|
|
14
|
+
docker: ## Build our docker image using the local pypi
|
|
15
|
+
$(MAKE) -C ../../idmtools_core dist
|
|
16
|
+
$(MAKE) -C ../../idmtools_models dist
|
|
17
|
+
$(MAKE) -C ../../idmtools_platform_comps dist
|
|
18
|
+
python build_docker_image.py
|
|
19
|
+
|
|
20
|
+
docker-release-staging: docker
|
|
21
|
+
python push_docker_image.py
|
ssmt_image/__init__.py
ADDED
ssmt_image/bootstrap.sh
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
echo "---> bootstrap.sh: Starting"
|
|
4
|
+
cd $COMPS_WORKING_DIR
|
|
5
|
+
echo "---> bootstrap.sh: Environment variables:"
|
|
6
|
+
env
|
|
7
|
+
echo "---> bootstrap.sh: End of environment variables."
|
|
8
|
+
|
|
9
|
+
if [[ $COMPS_WORKING_DIR != $PWD ]]; then
|
|
10
|
+
exit 254
|
|
11
|
+
fi
|
|
12
|
+
EXITCODE=255
|
|
13
|
+
if [[ -z "${COMPS_STARTUP_CMD// }" ]]; then
|
|
14
|
+
echo "---> bootstrap.sh: COMPS_STARTUP_CMD environment variable not specified."
|
|
15
|
+
else
|
|
16
|
+
echo Executing system command: $COMPS_STARTUP_CMD
|
|
17
|
+
eval "$COMPS_STARTUP_CMD"
|
|
18
|
+
EXITCODE=$?
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
if [[ -z "${COMPS_USER_CMD// }" ]]; then
|
|
22
|
+
echo "---> bootstrap.sh: COMPS_USER_CMD environment variable not specified."
|
|
23
|
+
else
|
|
24
|
+
echo Executing user command: $COMPS_USER_CMD
|
|
25
|
+
eval "$COMPS_USER_CMD"
|
|
26
|
+
EXITCODE=$?
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
echo "---> bootstrap.sh: Finished ($EXITCODE)"
|
|
30
|
+
exit $EXITCODE
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"""This script is currently a workaround so that we can use bump2version with docker since the nightly versions doesn't work with docker registry.
|
|
2
|
+
|
|
3
|
+
Notes:
|
|
4
|
+
If you are using this script locally, you need to set the environment variables *PYPI_STAGING_USERNAME* and *PYPI_STAGING_PASSWORD*.
|
|
5
|
+
These can be set to your idm email/password
|
|
6
|
+
|
|
7
|
+
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
|
|
8
|
+
"""
|
|
9
|
+
import argparse
|
|
10
|
+
import glob
|
|
11
|
+
import os
|
|
12
|
+
import shutil
|
|
13
|
+
import subprocess
|
|
14
|
+
from logging import getLogger, basicConfig, DEBUG, INFO
|
|
15
|
+
import sys
|
|
16
|
+
from getpass import getpass
|
|
17
|
+
import requests
|
|
18
|
+
from requests.auth import HTTPBasicAuth
|
|
19
|
+
import keyring
|
|
20
|
+
from natsort import natsorted
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
logger = getLogger(__name__)
|
|
24
|
+
# Global Configurations
|
|
25
|
+
KEYRING_NAME = "idmtools_ssmt_builder"
|
|
26
|
+
BASE_REPO = 'packages.idmod.org'
|
|
27
|
+
REPO_KEY = 'idm-docker-staging'
|
|
28
|
+
DOCKER_REPO = f'{REPO_KEY}.{BASE_REPO}'
|
|
29
|
+
IMAGE_NAME = 'idmtools/comps_ssmt_worker'
|
|
30
|
+
BASE_IMAGE_NAME = f'{DOCKER_REPO}/{IMAGE_NAME}'
|
|
31
|
+
CURRENT_DIRECTORY = os.path.dirname(__file__)
|
|
32
|
+
BASE_VERSION = open(os.path.join(CURRENT_DIRECTORY, '..', 'VERSION')).read().strip()
|
|
33
|
+
|
|
34
|
+
logger.info("Please be sure you are logged into the docker-production.packages.idmod.org Docker Repo")
|
|
35
|
+
BASE_DIR = os.path.abspath(os.path.join(CURRENT_DIRECTORY, '..', '..'))
|
|
36
|
+
LOCAL_PACKAGE_DIR = os.path.join(BASE_DIR, 'idmtools_platform_comps/ssmt_image')
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_dependency_packages():
|
|
40
|
+
"""
|
|
41
|
+
Get python packages required to build image.
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
None
|
|
45
|
+
"""
|
|
46
|
+
os.makedirs(os.path.abspath('.depends'), exist_ok=True)
|
|
47
|
+
for root, _dirs, files in os.walk(os.path.join(LOCAL_PACKAGE_DIR, '.depends')):
|
|
48
|
+
for file in files:
|
|
49
|
+
os.remove(os.path.join(root, file))
|
|
50
|
+
for package in ['idmtools_core', 'idmtools_models', 'idmtools_platform_comps']:
|
|
51
|
+
for file in glob.glob(os.path.join(BASE_DIR, package, 'dist', '**.gz')):
|
|
52
|
+
shutil.copy(file, os.path.join(LOCAL_PACKAGE_DIR, '.depends', os.path.basename(file)))
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def get_username_and_password(disable_keyring_load=False, disable_keyring_save=False):
|
|
56
|
+
"""
|
|
57
|
+
Try to get username.
|
|
58
|
+
|
|
59
|
+
It first attempts loading from environment vars, then keyring if not disabled, then lastly prompts.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
disable_keyring_load: Disable loading credentials from keyring
|
|
63
|
+
disable_keyring_save: Disable keyring save
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
Username password
|
|
67
|
+
"""
|
|
68
|
+
if 'PYPI_STAGING_USERNAME' in os.environ:
|
|
69
|
+
logger.info("Loading Credentials from environment")
|
|
70
|
+
if 'PYPI_STAGING_PASSWORD' not in os.environ:
|
|
71
|
+
logger.error("When specifying username from environment variable, you must also specify password")
|
|
72
|
+
sys.exit(-1)
|
|
73
|
+
username = os.environ['PYPI_STAGING_USERNAME']
|
|
74
|
+
password = os.environ['PYPI_STAGING_PASSWORD']
|
|
75
|
+
elif not disable_keyring_load and keyring.get_credential(KEYRING_NAME, "username"):
|
|
76
|
+
username = keyring.get_password(KEYRING_NAME, "username")
|
|
77
|
+
password = keyring.get_password(KEYRING_NAME, "password")
|
|
78
|
+
else:
|
|
79
|
+
username = input('Username:')
|
|
80
|
+
password = getpass(prompt='Password:')
|
|
81
|
+
if not disable_keyring_save:
|
|
82
|
+
logger.info("Saving Credentials")
|
|
83
|
+
keyring.set_password(KEYRING_NAME, "username", username)
|
|
84
|
+
keyring.set_password(KEYRING_NAME, "password", password)
|
|
85
|
+
return username, password
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def get_latest_image_version_from_registry(username, password):
|
|
89
|
+
"""
|
|
90
|
+
Fetch the latest image version from repo.
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
Latest version published in the registry
|
|
94
|
+
"""
|
|
95
|
+
url = f'https://{BASE_REPO}/artifactory/api/docker/{REPO_KEY}/v2/{IMAGE_NAME}/tags/list'
|
|
96
|
+
auth = HTTPBasicAuth(username=username, password=password)
|
|
97
|
+
logger.info(f"Loading Credentials from {url}")
|
|
98
|
+
response = requests.get(url, auth=auth)
|
|
99
|
+
logger.debug(f"Return Code: {response.status_code}")
|
|
100
|
+
if response.status_code != 200:
|
|
101
|
+
print(response.status_code)
|
|
102
|
+
print(response.content)
|
|
103
|
+
raise Exception('Could not load images')
|
|
104
|
+
else:
|
|
105
|
+
images = natsorted(response.json()['tags'], reverse=True)
|
|
106
|
+
images = [i for i in images if len(i) > 6]
|
|
107
|
+
logger.debug(f"Images: {images}")
|
|
108
|
+
last_version = images[0]
|
|
109
|
+
logger.info(f"Last Version {url}")
|
|
110
|
+
version_parts = last_version.split('.')
|
|
111
|
+
base_part = '.'.join(version_parts[:-1])
|
|
112
|
+
if BASE_VERSION in base_part:
|
|
113
|
+
version_parts[-1] = str(int(version_parts[-1]) + 1)
|
|
114
|
+
version = '.'.join(version_parts)
|
|
115
|
+
else:
|
|
116
|
+
version = f'{BASE_VERSION}.0'
|
|
117
|
+
logger.info(f"Next Version: {version}")
|
|
118
|
+
return version
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def build_image(username, password, disable_keyring_load, disable_keyring_save):
|
|
122
|
+
"""
|
|
123
|
+
Run the docker build command.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
username: Username to use with registry
|
|
127
|
+
password: Password to use with registry
|
|
128
|
+
disable_keyring_load: Disable keyring which caches passwords
|
|
129
|
+
disable_keyring_save: Disable caching password to the keyring
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
None
|
|
133
|
+
"""
|
|
134
|
+
if username is None or password is None:
|
|
135
|
+
username, password = get_username_and_password(disable_keyring_load, disable_keyring_save)
|
|
136
|
+
get_dependency_packages()
|
|
137
|
+
version = get_latest_image_version_from_registry(username, password)
|
|
138
|
+
cmd = ['docker', 'build', '--network=host', '--build-arg', f'SSMT_VERSION={version}', '--tag',
|
|
139
|
+
f'{DOCKER_REPO}/{IMAGE_NAME}:{version}', '.']
|
|
140
|
+
logger.info(f'Running: {" ".join(cmd)}')
|
|
141
|
+
p = subprocess.Popen(" ".join(cmd), cwd=os.path.abspath(os.path.dirname(__file__)), shell=True)
|
|
142
|
+
p.wait()
|
|
143
|
+
|
|
144
|
+
if p.returncode == 0:
|
|
145
|
+
logger.info("Tagging image")
|
|
146
|
+
os.system(f'docker tag {DOCKER_REPO}/{IMAGE_NAME}:{version} {DOCKER_REPO}/{IMAGE_NAME}:{version[:-2]}')
|
|
147
|
+
sys.exit(p.returncode)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
if __name__ == "__main__":
|
|
151
|
+
parser = argparse.ArgumentParser("Build SSMT Image")
|
|
152
|
+
parser.add_argument("--username", default=None, help="Docker Production Username")
|
|
153
|
+
parser.add_argument("--password", default=None, help="Docker Production Password")
|
|
154
|
+
parser.add_argument("--disable-keyring-load", default=False, help="Disable loading password from keyring")
|
|
155
|
+
parser.add_argument("--disable-keyring-save", default=False, help="Disable saving password to keyring after user prompts")
|
|
156
|
+
parser.add_argument("--verbose", default=False, help="Enable Debug logging")
|
|
157
|
+
parser.add_argument("--debug", default=False, help="Enable Debug logging")
|
|
158
|
+
args = parser.parse_args()
|
|
159
|
+
|
|
160
|
+
basicConfig(filename="build.log", level=DEBUG if any([args.verbose, args.debug]) else INFO)
|
|
161
|
+
build_image(args.username, args.password, args.disable_keyring_load, args.disable_keyring_save)
|
ssmt_image/pip.conf
ADDED