metaflow 2.14.2__py2.py3-none-any.whl → 2.15.0__py2.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.
- metaflow/cmd/make_wrapper.py +16 -0
- metaflow/metaflow_config.py +3 -0
- metaflow/plugins/aws/batch/batch_cli.py +4 -4
- metaflow/plugins/aws/batch/batch_decorator.py +8 -0
- metaflow/plugins/pypi/bootstrap.py +5 -5
- metaflow/runner/subprocess_manager.py +12 -6
- metaflow/version.py +1 -1
- metaflow-2.15.0.data/data/share/metaflow/devtools/Makefile +323 -0
- metaflow-2.15.0.data/data/share/metaflow/devtools/Tiltfile +607 -0
- metaflow-2.15.0.data/data/share/metaflow/devtools/pick_services.sh +104 -0
- {metaflow-2.14.2.dist-info → metaflow-2.15.0.dist-info}/METADATA +3 -3
- {metaflow-2.14.2.dist-info → metaflow-2.15.0.dist-info}/RECORD +16 -12
- {metaflow-2.14.2.dist-info → metaflow-2.15.0.dist-info}/WHEEL +1 -1
- {metaflow-2.14.2.dist-info → metaflow-2.15.0.dist-info}/entry_points.txt +1 -0
- {metaflow-2.14.2.dist-info → metaflow-2.15.0.dist-info}/LICENSE +0 -0
- {metaflow-2.14.2.dist-info → metaflow-2.15.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
import sys
|
2
|
+
import subprocess
|
3
|
+
from pathlib import Path
|
4
|
+
import sysconfig
|
5
|
+
|
6
|
+
|
7
|
+
def main():
|
8
|
+
share_dir = Path(sysconfig.get_paths()["data"]) / "share" / "metaflow" / "devtools"
|
9
|
+
makefile_path = share_dir / "Makefile"
|
10
|
+
cmd = ["make", "-f", str(makefile_path)] + sys.argv[1:]
|
11
|
+
# subprocess.run(cmd, check=True)
|
12
|
+
try:
|
13
|
+
completed = subprocess.run(cmd, check=True)
|
14
|
+
sys.exit(completed.returncode)
|
15
|
+
except subprocess.CalledProcessError as ex:
|
16
|
+
sys.exit(ex.returncode)
|
metaflow/metaflow_config.py
CHANGED
@@ -432,6 +432,9 @@ CONDA_PACKAGE_GSROOT = from_conf("CONDA_PACKAGE_GSROOT")
|
|
432
432
|
# should result in an appreciable speedup in flow environment initialization.
|
433
433
|
CONDA_DEPENDENCY_RESOLVER = from_conf("CONDA_DEPENDENCY_RESOLVER", "conda")
|
434
434
|
|
435
|
+
# Default to not using fast init binary.
|
436
|
+
CONDA_USE_FAST_INIT = from_conf("CONDA_USE_FAST_INIT", False)
|
437
|
+
|
435
438
|
###
|
436
439
|
# Escape hatch configuration
|
437
440
|
###
|
@@ -211,7 +211,7 @@ def step(
|
|
211
211
|
log_driver=None,
|
212
212
|
log_options=None,
|
213
213
|
num_parallel=None,
|
214
|
-
**kwargs
|
214
|
+
**kwargs,
|
215
215
|
):
|
216
216
|
def echo(msg, stream="stderr", batch_id=None, **kwargs):
|
217
217
|
msg = util.to_unicode(msg)
|
@@ -273,11 +273,11 @@ def step(
|
|
273
273
|
"metaflow_version"
|
274
274
|
]
|
275
275
|
|
276
|
+
env = {"METAFLOW_FLOW_FILENAME": os.path.basename(sys.argv[0])}
|
277
|
+
|
276
278
|
env_deco = [deco for deco in node.decorators if deco.name == "environment"]
|
277
279
|
if env_deco:
|
278
|
-
env
|
279
|
-
else:
|
280
|
-
env = {}
|
280
|
+
env.update(env_deco[0].attributes["vars"])
|
281
281
|
|
282
282
|
# Add the environment variables related to the input-paths argument
|
283
283
|
if split_vars:
|
@@ -298,6 +298,13 @@ class BatchDecorator(StepDecorator):
|
|
298
298
|
self._save_logs_sidecar = Sidecar("save_logs_periodically")
|
299
299
|
self._save_logs_sidecar.start()
|
300
300
|
|
301
|
+
# Start spot termination monitor sidecar.
|
302
|
+
current._update_env(
|
303
|
+
{"spot_termination_notice": "/tmp/spot_termination_notice"}
|
304
|
+
)
|
305
|
+
self._spot_monitor_sidecar = Sidecar("spot_termination_monitor")
|
306
|
+
self._spot_monitor_sidecar.start()
|
307
|
+
|
301
308
|
num_parallel = int(os.environ.get("AWS_BATCH_JOB_NUM_NODES", 0))
|
302
309
|
if num_parallel >= 1 and ubf_context == UBF_CONTROL:
|
303
310
|
# UBF handling for multinode case
|
@@ -350,6 +357,7 @@ class BatchDecorator(StepDecorator):
|
|
350
357
|
|
351
358
|
try:
|
352
359
|
self._save_logs_sidecar.terminate()
|
360
|
+
self._spot_monitor_sidecar.terminate()
|
353
361
|
except:
|
354
362
|
# Best effort kill
|
355
363
|
pass
|
@@ -10,7 +10,7 @@ import tarfile
|
|
10
10
|
import time
|
11
11
|
from urllib.error import URLError
|
12
12
|
from urllib.request import urlopen
|
13
|
-
from metaflow.metaflow_config import DATASTORE_LOCAL_DIR
|
13
|
+
from metaflow.metaflow_config import DATASTORE_LOCAL_DIR, CONDA_USE_FAST_INIT
|
14
14
|
from metaflow.plugins import DATASTORES
|
15
15
|
from metaflow.plugins.pypi.utils import MICROMAMBA_MIRROR_URL, MICROMAMBA_URL
|
16
16
|
from metaflow.util import which
|
@@ -19,7 +19,7 @@ import warnings
|
|
19
19
|
|
20
20
|
from . import MAGIC_FILE, _datastore_packageroot
|
21
21
|
|
22
|
-
FAST_INIT_BIN_URL = "https://fast-flow-init.outerbounds.sh/{platform}/
|
22
|
+
FAST_INIT_BIN_URL = "https://fast-flow-init.outerbounds.sh/{platform}/latest"
|
23
23
|
|
24
24
|
# Bootstraps a valid conda virtual environment composed of conda and pypi packages
|
25
25
|
|
@@ -329,6 +329,8 @@ if __name__ == "__main__":
|
|
329
329
|
|
330
330
|
@timer
|
331
331
|
def fast_setup_environment(architecture, storage, env, prefix, pkgs_dir):
|
332
|
+
install_fast_initializer(architecture)
|
333
|
+
|
332
334
|
# Get package urls
|
333
335
|
conda_pkgs = env["conda"]
|
334
336
|
pypi_pkgs = env.get("pypi", [])
|
@@ -379,9 +381,7 @@ if __name__ == "__main__":
|
|
379
381
|
with open(os.path.join(manifest_dir, MAGIC_FILE)) as f:
|
380
382
|
env = json.load(f)[id_][architecture]
|
381
383
|
|
382
|
-
if
|
383
|
-
# TODO: Remove this once fast-initializer is ready for all datastores
|
384
|
-
install_fast_initializer(architecture)
|
384
|
+
if CONDA_USE_FAST_INIT:
|
385
385
|
fast_setup_environment(architecture, storage, env, prefix, pkgs_dir)
|
386
386
|
else:
|
387
387
|
setup_environment(
|
@@ -78,13 +78,19 @@ class SubprocessManager(object):
|
|
78
78
|
self.commands: Dict[int, CommandManager] = {}
|
79
79
|
|
80
80
|
try:
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
81
|
+
try:
|
82
|
+
loop = asyncio.get_running_loop()
|
83
|
+
loop.add_signal_handler(
|
84
|
+
signal.SIGINT,
|
85
|
+
lambda: asyncio.create_task(self._async_handle_sigint()),
|
86
|
+
)
|
87
|
+
except RuntimeError:
|
88
|
+
signal.signal(signal.SIGINT, self._handle_sigint)
|
89
|
+
except ValueError:
|
90
|
+
sys.stderr.write(
|
91
|
+
"Warning: Unable to set signal handlers in non-main thread. "
|
92
|
+
"Interrupt handling will be limited.\n"
|
85
93
|
)
|
86
|
-
except RuntimeError:
|
87
|
-
signal.signal(signal.SIGINT, self._handle_sigint)
|
88
94
|
|
89
95
|
async def _async_handle_sigint(self):
|
90
96
|
pids = [
|
metaflow/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
metaflow_version = "2.
|
1
|
+
metaflow_version = "2.15.0"
|
@@ -0,0 +1,323 @@
|
|
1
|
+
SHELL := /bin/bash
|
2
|
+
.SHELLFLAGS := -eu -o pipefail -c
|
3
|
+
|
4
|
+
help:
|
5
|
+
@echo "Available targets:"
|
6
|
+
@echo " up - Start the development environment"
|
7
|
+
@echo " shell - Switch to development environment's shell"
|
8
|
+
@echo " ui - Open Metaflow UI"
|
9
|
+
@echo " dashboard - Open Minikube dashboard"
|
10
|
+
@echo " down - Stop and clean up the environment"
|
11
|
+
@echo " help - Show this help message"
|
12
|
+
|
13
|
+
HELM_VERSION := v3.14.0
|
14
|
+
MINIKUBE_VERSION := v1.32.0
|
15
|
+
TILT_VERSION := v0.33.11
|
16
|
+
GUM_VERSION := v0.15.2
|
17
|
+
|
18
|
+
MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
|
19
|
+
MKFILE_DIR := $(dir $(MKFILE_PATH))
|
20
|
+
DEVTOOLS_DIR := $(MKFILE_DIR).devtools
|
21
|
+
PICK_SERVICES := $(MKFILE_DIR)pick_services.sh
|
22
|
+
MINIKUBE_DIR := $(DEVTOOLS_DIR)/minikube
|
23
|
+
MINIKUBE := $(MINIKUBE_DIR)/minikube
|
24
|
+
TILT_DIR := $(DEVTOOLS_DIR)/tilt
|
25
|
+
TILT := $(TILT_DIR)/tilt
|
26
|
+
TILTFILE := $(MKFILE_DIR)/Tiltfile
|
27
|
+
MAKE_CMD := $(MAKE) -C "$(MKFILE_DIR)"
|
28
|
+
|
29
|
+
MINIKUBE_CPUS ?= 4
|
30
|
+
MINIKUBE_MEMORY ?= 6000
|
31
|
+
MINIKUBE_DISK_SIZE ?= 20g
|
32
|
+
|
33
|
+
ifeq ($(shell uname), Darwin)
|
34
|
+
minikube_os = darwin
|
35
|
+
tilt_os = mac
|
36
|
+
else
|
37
|
+
minikube_os = linux
|
38
|
+
tilt_os = linux
|
39
|
+
endif
|
40
|
+
|
41
|
+
ifeq ($(shell uname -m), x86_64)
|
42
|
+
arch = amd64
|
43
|
+
tilt_arch = x86_64
|
44
|
+
else
|
45
|
+
arch = arm64
|
46
|
+
tilt_arch = arm64
|
47
|
+
endif
|
48
|
+
|
49
|
+
# TODO: Move scripts to a folder
|
50
|
+
|
51
|
+
install-helm:
|
52
|
+
@if ! command -v helm >/dev/null 2>&1; then \
|
53
|
+
echo "📥 Installing Helm $(HELM_VERSION) (may require sudo access)..."; \
|
54
|
+
curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | HELM_INSTALL_VERSION=$(HELM_VERSION) bash; \
|
55
|
+
echo "✅ Helm installation complete"; \
|
56
|
+
fi
|
57
|
+
|
58
|
+
check-docker:
|
59
|
+
@if ! command -v docker >/dev/null 2>&1; then \
|
60
|
+
echo "❌ Docker is not installed. Please install Docker first: https://docs.docker.com/get-docker/"; \
|
61
|
+
exit 1; \
|
62
|
+
fi
|
63
|
+
@echo "🔍 Checking Docker daemon..."
|
64
|
+
@if [ "$(shell uname)" = "Darwin" ]; then \
|
65
|
+
open -a Docker || (echo "❌ Please start Docker Desktop" && exit 1); \
|
66
|
+
else \
|
67
|
+
systemctl is-active --quiet docker || (echo "❌ Docker daemon is not running. Start with 'sudo systemctl start docker'" && exit 1); \
|
68
|
+
fi
|
69
|
+
@echo "✅ Docker is running"
|
70
|
+
|
71
|
+
install-brew:
|
72
|
+
@if [ "$(shell uname)" = "Darwin" ] && ! command -v brew >/dev/null 2>&1; then \
|
73
|
+
echo "📥 Installing Homebrew..."; \
|
74
|
+
/bin/bash -c "$$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"; \
|
75
|
+
echo "✅ Homebrew installation complete"; \
|
76
|
+
fi
|
77
|
+
|
78
|
+
install-curl:
|
79
|
+
@if ! command -v curl >/dev/null 2>&1; then \
|
80
|
+
echo "📥 Installing curl..."; \
|
81
|
+
if [ "$(shell uname)" = "Darwin" ]; then \
|
82
|
+
HOMEBREW_NO_AUTO_UPDATE=1 brew install curl; \
|
83
|
+
elif command -v apt-get >/dev/null 2>&1; then \
|
84
|
+
sudo apt-get update && sudo apt-get install -y curl; \
|
85
|
+
elif command -v yum >/dev/null 2>&1; then \
|
86
|
+
sudo yum install -y curl; \
|
87
|
+
elif command -v dnf >/dev/null 2>&1; then \
|
88
|
+
sudo dnf install -y curl; \
|
89
|
+
else \
|
90
|
+
echo "❌ Could not install curl. Please install manually."; \
|
91
|
+
exit 1; \
|
92
|
+
fi; \
|
93
|
+
echo "✅ curl installation complete"; \
|
94
|
+
fi
|
95
|
+
|
96
|
+
install-gum:
|
97
|
+
@echo "🔍 Checking if gum is installed..."
|
98
|
+
@if ! command -v gum >/dev/null 2>&1; then \
|
99
|
+
echo "📥 Installing gum..."; \
|
100
|
+
if [ "$(shell uname)" = "Darwin" ]; then \
|
101
|
+
HOMEBREW_NO_AUTO_UPDATE=1 brew install gum; \
|
102
|
+
elif command -v apt-get >/dev/null 2>&1; then \
|
103
|
+
curl -fsSL -o /tmp/gum.deb \
|
104
|
+
"https://github.com/charmbracelet/gum/releases/download/$(GUM_VERSION)/gum_$(GUM_VERSION:v%=%)_$(arch).deb"; \
|
105
|
+
sudo apt-get update -qq; \
|
106
|
+
sudo apt-get install -y /tmp/gum.deb || sudo dpkg -i /tmp/gum.deb; \
|
107
|
+
rm -f /tmp/gum.deb; \
|
108
|
+
else \
|
109
|
+
echo "❌ Could not determine how to install gum for your platform. Please install manually."; \
|
110
|
+
exit 1; \
|
111
|
+
fi; \
|
112
|
+
echo "✅ gum installation complete"; \
|
113
|
+
else \
|
114
|
+
echo "✅ gum is already installed."; \
|
115
|
+
fi
|
116
|
+
|
117
|
+
setup-minikube:
|
118
|
+
@if [ ! -f "$(MINIKUBE)" ]; then \
|
119
|
+
echo "📥 Installing Minikube $(MINIKUBE_VERSION)"; \
|
120
|
+
mkdir -p $(MINIKUBE_DIR); \
|
121
|
+
curl -L --fail https://github.com/kubernetes/minikube/releases/download/$(MINIKUBE_VERSION)/minikube-$(minikube_os)-$(arch) -o $(MINIKUBE) || (echo "❌ Failed to download minikube" && exit 1); \
|
122
|
+
chmod +x $(MINIKUBE); \
|
123
|
+
echo "✅ Minikube $(MINIKUBE_VERSION) installed successfully"; \
|
124
|
+
fi
|
125
|
+
@echo "🔧 Setting up Minikube $(MINIKUBE_VERSION) cluster..."
|
126
|
+
@if ! $(MINIKUBE) status >/dev/null 2>&1; then \
|
127
|
+
echo "🚀 Starting new Minikube $(MINIKUBE_VERSION) cluster..."; \
|
128
|
+
$(MINIKUBE) start \
|
129
|
+
--cpus $(MINIKUBE_CPUS) \
|
130
|
+
--memory $(MINIKUBE_MEMORY) \
|
131
|
+
--disk-size $(MINIKUBE_DISK_SIZE) \
|
132
|
+
--driver docker; \
|
133
|
+
echo "🔌 Enabling metrics-server and dashboard (quietly)..."; \
|
134
|
+
$(MINIKUBE) addons enable metrics-server >/dev/null 2>&1; \
|
135
|
+
$(MINIKUBE) addons enable dashboard >/dev/null 2>&1; \
|
136
|
+
else \
|
137
|
+
echo "✅ Minikube $(MINIKUBE_VERSION) cluster is already running"; \
|
138
|
+
fi
|
139
|
+
@echo "🎉 Minikube $(MINIKUBE_VERSION) cluster is ready!"
|
140
|
+
|
141
|
+
setup-tilt:
|
142
|
+
@if [ ! -f "$(TILT)" ]; then \
|
143
|
+
echo "📥 Installing Tilt $(TILT_VERSION)"; \
|
144
|
+
mkdir -p $(TILT_DIR); \
|
145
|
+
(curl -L https://github.com/tilt-dev/tilt/releases/download/$(TILT_VERSION)/tilt.$(TILT_VERSION:v%=%).$(tilt_os).$(tilt_arch).tar.gz | tar -xz -C $(TILT_DIR)) && echo "✅ Tilt $(TILT_VERSION) installed successfully" || (echo "❌ Failed to install Tilt" && exit 1); \
|
146
|
+
fi
|
147
|
+
|
148
|
+
tunnel:
|
149
|
+
$(MINIKUBE) tunnel
|
150
|
+
|
151
|
+
teardown-minikube:
|
152
|
+
@echo "🛑 Stopping Minikube $(MINIKUBE_VERSION) cluster..."
|
153
|
+
-$(MINIKUBE) stop
|
154
|
+
@echo "🗑️ Deleting Minikube $(MINIKUBE_VERSION) cluster..."
|
155
|
+
-$(MINIKUBE) delete --all
|
156
|
+
@echo "🧹 Removing Minikube binary..."
|
157
|
+
-rm -rf $(MINIKUBE_DIR)
|
158
|
+
@echo "✅ Minikube $(MINIKUBE_VERSION) teardown complete"
|
159
|
+
|
160
|
+
dashboard:
|
161
|
+
@echo "🔗 Opening Minikube Dashboard..."
|
162
|
+
@$(MINIKUBE) dashboard
|
163
|
+
|
164
|
+
# make shell is symlinked to metaflow-dev shell by metaflow
|
165
|
+
up: install-brew check-docker install-curl install-gum setup-minikube install-helm setup-tilt
|
166
|
+
@echo "🚀 Starting up (may require sudo access)..."
|
167
|
+
@mkdir -p $(DEVTOOLS_DIR)
|
168
|
+
@echo '#!/bin/bash' > $(DEVTOOLS_DIR)/start.sh
|
169
|
+
@echo 'set -e' >> $(DEVTOOLS_DIR)/start.sh
|
170
|
+
@echo 'trap "exit" INT TERM' >> $(DEVTOOLS_DIR)/start.sh
|
171
|
+
@echo 'trap "kill 0" EXIT' >> $(DEVTOOLS_DIR)/start.sh
|
172
|
+
@echo 'eval $$($(MINIKUBE) docker-env)' >> $(DEVTOOLS_DIR)/start.sh
|
173
|
+
|
174
|
+
@echo 'if [ -n "$$SERVICES_OVERRIDE" ]; then' >> "$(DEVTOOLS_DIR)/start.sh"
|
175
|
+
@echo ' echo "🌐 Using user-provided list of services: $$SERVICES_OVERRIDE"' >> "$(DEVTOOLS_DIR)/start.sh"
|
176
|
+
@echo ' SERVICES="$$SERVICES_OVERRIDE"' >> "$(DEVTOOLS_DIR)/start.sh"
|
177
|
+
@echo 'else' >> "$(DEVTOOLS_DIR)/start.sh"
|
178
|
+
@echo ' echo "📝 Selecting services..."' >> "$(DEVTOOLS_DIR)/start.sh"
|
179
|
+
@echo ' SERVICES=$$($(PICK_SERVICES))' >> "$(DEVTOOLS_DIR)/start.sh"
|
180
|
+
@echo 'fi' >> "$(DEVTOOLS_DIR)/start.sh"
|
181
|
+
@echo 'PATH="$(MINIKUBE_DIR):$(TILT_DIR):$$PATH" $(MINIKUBE) tunnel &' >> $(DEVTOOLS_DIR)/start.sh
|
182
|
+
@echo 'echo -e "🚀 Starting Tilt with selected services..."' >> $(DEVTOOLS_DIR)/start.sh
|
183
|
+
@echo 'echo -e "\033[1;38;5;46m\n🔥 \033[1;38;5;196mNext Steps:\033[0;38;5;46m Use \033[3mmetaflow-dev shell\033[23m to switch to the development\n environment'\''s shell and start executing your Metaflow flows.\n\033[0m"' >> "$(DEVTOOLS_DIR)/start.sh"
|
184
|
+
@echo 'PATH="$(MINIKUBE_DIR):$(TILT_DIR):$$PATH" SERVICES="$$SERVICES" tilt up -f $(TILTFILE)' >> $(DEVTOOLS_DIR)/start.sh
|
185
|
+
@echo 'wait' >> $(DEVTOOLS_DIR)/start.sh
|
186
|
+
@chmod +x $(DEVTOOLS_DIR)/start.sh
|
187
|
+
@$(DEVTOOLS_DIR)/start.sh
|
188
|
+
|
189
|
+
down:
|
190
|
+
@echo "🛑 Stopping all services..."
|
191
|
+
@-pkill -f "$(MINIKUBE) tunnel" 2>/dev/null || true
|
192
|
+
@echo "⏹️ Stopping Tilt..."
|
193
|
+
-PATH="$(MINIKUBE_DIR):$(TILT_DIR):$$PATH" tilt down -f $(TILTFILE)
|
194
|
+
@echo "🧹 Cleaning up Minikube..."
|
195
|
+
$(MAKE_CMD) teardown-minikube
|
196
|
+
@echo "🗑️ Removing Tilt binary and directory..."
|
197
|
+
-rm -rf $(TILT_DIR)
|
198
|
+
@echo "🧹 Removing temporary scripts..."
|
199
|
+
-rm -rf $(DEVTOOLS_DIR)
|
200
|
+
@echo "✨ All done!"
|
201
|
+
|
202
|
+
shell: setup-tilt
|
203
|
+
@echo "⏳ Checking if development environment is up..."
|
204
|
+
@set -e; \
|
205
|
+
for i in $$(seq 1 90); do \
|
206
|
+
if "$(TILT)" get session >/dev/null 2>&1; then \
|
207
|
+
found_session=1; \
|
208
|
+
break; \
|
209
|
+
else \
|
210
|
+
sleep 2; \
|
211
|
+
fi; \
|
212
|
+
done; \
|
213
|
+
if [ -z "$${found_session}" ]; then \
|
214
|
+
echo "❌ Development environment is not up."; \
|
215
|
+
echo " Please run 'metaflow-dev up' in another terminal, then re-run 'metaflow-dev shell'."; \
|
216
|
+
exit 1; \
|
217
|
+
fi
|
218
|
+
@echo "⏳ Waiting for development environment to be ready..."
|
219
|
+
@while true; do \
|
220
|
+
"$(TILT)" get uiresource generate-configs >/dev/null 2>&1; \
|
221
|
+
status=$$?; \
|
222
|
+
if [ $$status -eq 0 ]; then \
|
223
|
+
"$(TILT)" wait --for=condition=Ready uiresource/generate-configs; \
|
224
|
+
break; \
|
225
|
+
elif [ $$status -eq 127 ]; then \
|
226
|
+
echo "❌ Development environment is not up."; \
|
227
|
+
echo " Please run 'metaflow-dev up' in another terminal, then re-run 'metaflow-dev shell'."; \
|
228
|
+
exit 1; \
|
229
|
+
else \
|
230
|
+
sleep 1; \
|
231
|
+
fi; \
|
232
|
+
done
|
233
|
+
@echo "🔧 Starting a new shell for development environment..."
|
234
|
+
@bash -c '\
|
235
|
+
if [ -n "$$SHELL" ]; then \
|
236
|
+
user_shell="$$SHELL"; \
|
237
|
+
else \
|
238
|
+
user_shell="$(SHELL)"; \
|
239
|
+
fi; \
|
240
|
+
echo "🔎 Using $$user_shell for interactive session."; \
|
241
|
+
echo "🐍 If you installed Metaflow in a virtual environment, activate it now."; \
|
242
|
+
if [ -f "$(DEVTOOLS_DIR)/aws_config" ]; then \
|
243
|
+
env METAFLOW_HOME="$(DEVTOOLS_DIR)" \
|
244
|
+
METAFLOW_PROFILE=local \
|
245
|
+
AWS_CONFIG_FILE="$(DEVTOOLS_DIR)/aws_config" \
|
246
|
+
"$$user_shell" -i; \
|
247
|
+
else \
|
248
|
+
env METAFLOW_HOME="$(DEVTOOLS_DIR)" \
|
249
|
+
METAFLOW_PROFILE=local \
|
250
|
+
"$$user_shell" -i; \
|
251
|
+
fi'
|
252
|
+
|
253
|
+
# TODO: This can be done away with in a while since we now have metaflow-dev command.
|
254
|
+
#
|
255
|
+
# @echo '$(MAKE_CMD) create-dev-shell' >> $(DEVTOOLS_DIR)/start.sh
|
256
|
+
# @echo 'rm -f /tmp/metaflow-devshell-*' >> $(DEVTOOLS_DIR)/start.sh
|
257
|
+
create-dev-shell: setup-tilt
|
258
|
+
@bash -c '\
|
259
|
+
SHELL_PATH=/tmp/metaflow-dev-shell-$$$$ && \
|
260
|
+
echo "#!/bin/bash" > $$SHELL_PATH && \
|
261
|
+
echo "set -e" >> $$SHELL_PATH && \
|
262
|
+
echo "" >> $$SHELL_PATH && \
|
263
|
+
echo "echo \"⏳ Checking if development environment is up...\"" >> $$SHELL_PATH && \
|
264
|
+
echo "if ! $(TILT) get session >/dev/null 2>&1; then" >> $$SHELL_PATH && \
|
265
|
+
echo " echo \"❌ Development environment is not up.\"" >> $$SHELL_PATH && \
|
266
|
+
echo " echo \" Please run '\''make up'\'' in another terminal, then re-run this script.\"" >> $$SHELL_PATH && \
|
267
|
+
echo " exit 1" >> $$SHELL_PATH && \
|
268
|
+
echo "fi" >> $$SHELL_PATH && \
|
269
|
+
echo "" >> $$SHELL_PATH && \
|
270
|
+
echo "echo \"⏳ Waiting for development environment to be ready...\"" >> $$SHELL_PATH && \
|
271
|
+
echo "$(TILT) wait --for=condition=Ready uiresource/generate-configs" >> $$SHELL_PATH && \
|
272
|
+
echo "" >> $$SHELL_PATH && \
|
273
|
+
echo "echo \"🔧 Starting a new shell for development environment...\"" >> $$SHELL_PATH && \
|
274
|
+
echo "if [ -n \"\$$SHELL\" ]; then" >> $$SHELL_PATH && \
|
275
|
+
echo " user_shell=\"\$$SHELL\"" >> $$SHELL_PATH && \
|
276
|
+
echo "else" >> $$SHELL_PATH && \
|
277
|
+
echo " user_shell=\"$(SHELL)\"" >> $$SHELL_PATH && \
|
278
|
+
echo "fi" >> $$SHELL_PATH && \
|
279
|
+
echo "echo \"🔎 Using \$$user_shell for interactive session.\"" >> $$SHELL_PATH && \
|
280
|
+
echo "echo \"🐍 If you installed Metaflow in a virtual environment, activate it now.\"" >> $$SHELL_PATH && \
|
281
|
+
echo "if [ -f \"$(DEVTOOLS_DIR)/aws_config\" ]; then" >> $$SHELL_PATH && \
|
282
|
+
echo " env METAFLOW_HOME=\"$(DEVTOOLS_DIR)\" \\" >> $$SHELL_PATH && \
|
283
|
+
echo " METAFLOW_PROFILE=local \\" >> $$SHELL_PATH && \
|
284
|
+
echo " AWS_CONFIG_FILE=\"$(DEVTOOLS_DIR)/aws_config\" \\" >> $$SHELL_PATH && \
|
285
|
+
echo " \"\$$user_shell\" -i" >> $$SHELL_PATH && \
|
286
|
+
echo "else" >> $$SHELL_PATH && \
|
287
|
+
echo " env METAFLOW_HOME=\"$(DEVTOOLS_DIR)\" \\" >> $$SHELL_PATH && \
|
288
|
+
echo " METAFLOW_PROFILE=local \\" >> $$SHELL_PATH && \
|
289
|
+
echo " \"\$$user_shell\" -i" >> $$SHELL_PATH && \
|
290
|
+
echo "fi" >> $$SHELL_PATH && \
|
291
|
+
chmod +x $$SHELL_PATH && \
|
292
|
+
echo "✨ Created $$SHELL_PATH" && \
|
293
|
+
echo "🔑 Execute it from ANY directory to switch to development environment shell!" \
|
294
|
+
'
|
295
|
+
|
296
|
+
ui: setup-tilt
|
297
|
+
@echo "⏳ Checking if the development environment is up..."
|
298
|
+
@if ! $(TILT) get session >/dev/null 2>&1; then \
|
299
|
+
echo "❌ Development environment is not up."; \
|
300
|
+
echo " Please run 'metaflow-dev up' in another terminal, then re-run 'metaflow-dev ui'."; \
|
301
|
+
exit 1; \
|
302
|
+
fi
|
303
|
+
@echo "⏳ Waiting for Metaflow UI to be ready..."
|
304
|
+
@while true; do \
|
305
|
+
"$(TILT)" get uiresource metaflow-ui >/dev/null 2>&1; \
|
306
|
+
status=$$?; \
|
307
|
+
if [ $$status -eq 0 ]; then \
|
308
|
+
"$(TILT)" wait --for=condition=Ready uiresource/metaflow-ui; \
|
309
|
+
break; \
|
310
|
+
elif [ $$status -eq 127 ]; then \
|
311
|
+
echo "❌ Development environment is not up."; \
|
312
|
+
echo " Please run 'metaflow-dev up' in another terminal, then re-run 'metaflow-dev shell'."; \
|
313
|
+
exit 1; \
|
314
|
+
else \
|
315
|
+
sleep 1; \
|
316
|
+
fi; \
|
317
|
+
done
|
318
|
+
@echo "🔗 Opening Metaflow UI at http://localhost:3000"
|
319
|
+
@open http://localhost:3000
|
320
|
+
|
321
|
+
.PHONY: install-helm setup-minikube setup-tilt teardown-minikube tunnel up down check-docker install-curl install-gum install-brew up down dashboard shell ui help
|
322
|
+
|
323
|
+
.DEFAULT_GOAL := up
|
@@ -0,0 +1,607 @@
|
|
1
|
+
# Tilt configuration for running Metaflow on a local Kubernetes stack
|
2
|
+
#
|
3
|
+
# Usage:
|
4
|
+
# Start the development environment:
|
5
|
+
# $ tilt up
|
6
|
+
# Stop and clean up:
|
7
|
+
# $ tilt down
|
8
|
+
|
9
|
+
# TODO:
|
10
|
+
# 1. move away from temporary images
|
11
|
+
# 2. introduce kueue and jobsets
|
12
|
+
# 3. lock versions
|
13
|
+
|
14
|
+
version_settings(constraint='>=0.22.2')
|
15
|
+
allow_k8s_contexts('minikube')
|
16
|
+
|
17
|
+
components = {
|
18
|
+
"metadata-service": ["postgresql"],
|
19
|
+
"ui": ["postgresql", "minio"],
|
20
|
+
"minio": [],
|
21
|
+
"postgresql": [],
|
22
|
+
"argo-workflows": [],
|
23
|
+
"argo-events": ["argo-workflows"],
|
24
|
+
}
|
25
|
+
|
26
|
+
if os.getenv("SERVICES", "").strip():
|
27
|
+
requested_components = os.getenv("SERVICES", "").split(",")
|
28
|
+
else:
|
29
|
+
requested_components = list(components.keys())
|
30
|
+
|
31
|
+
metaflow_config = {}
|
32
|
+
metaflow_config["METAFLOW_KUBERNETES_NAMESPACE"] = "default"
|
33
|
+
|
34
|
+
aws_config = []
|
35
|
+
|
36
|
+
def write_config_files():
|
37
|
+
metaflow_json = encode_json(metaflow_config)
|
38
|
+
cmd = '''cat > .devtools/config_local.json <<EOF
|
39
|
+
%s
|
40
|
+
EOF
|
41
|
+
''' % (metaflow_json)
|
42
|
+
if aws_config and aws_config.strip():
|
43
|
+
cmd += '''cat > .devtools/aws_config <<EOF
|
44
|
+
%s
|
45
|
+
EOF
|
46
|
+
''' % (aws_config.strip())
|
47
|
+
return cmd
|
48
|
+
|
49
|
+
load('ext://helm_resource', 'helm_resource', 'helm_repo')
|
50
|
+
load('ext://helm_remote', 'helm_remote')
|
51
|
+
|
52
|
+
|
53
|
+
def resolve(component, resolved=None):
|
54
|
+
if resolved == None:
|
55
|
+
resolved = []
|
56
|
+
if component in resolved:
|
57
|
+
return resolved
|
58
|
+
if component in components:
|
59
|
+
for dep in components[component]:
|
60
|
+
resolve(dep, resolved)
|
61
|
+
resolved.append(component)
|
62
|
+
return resolved
|
63
|
+
|
64
|
+
valid_components = []
|
65
|
+
for component in components.keys():
|
66
|
+
if component not in valid_components:
|
67
|
+
valid_components.append(component)
|
68
|
+
for deps in components.values():
|
69
|
+
for dep in deps:
|
70
|
+
if dep not in valid_components:
|
71
|
+
valid_components.append(dep)
|
72
|
+
|
73
|
+
enabled_components = []
|
74
|
+
for component in requested_components:
|
75
|
+
if component not in valid_components:
|
76
|
+
fail("Unknown component: " + component)
|
77
|
+
for result in resolve(component):
|
78
|
+
if result not in enabled_components:
|
79
|
+
enabled_components.append(result)
|
80
|
+
|
81
|
+
# Print a friendly summary when running `tilt up`.
|
82
|
+
if config.tilt_subcommand == 'up':
|
83
|
+
print("\n📦 Components to install:")
|
84
|
+
for component in enabled_components:
|
85
|
+
print("• " + component)
|
86
|
+
if component in components and components[component]:
|
87
|
+
print(" ↳ requires: " + ", ".join(components[component]))
|
88
|
+
|
89
|
+
config_resources = []
|
90
|
+
|
91
|
+
#################################################
|
92
|
+
# MINIO
|
93
|
+
#################################################
|
94
|
+
if "minio" in enabled_components:
|
95
|
+
helm_remote(
|
96
|
+
'minio',
|
97
|
+
repo_name='minio-s3',
|
98
|
+
repo_url='https://charts.min.io/',
|
99
|
+
set=[
|
100
|
+
'rootUser=rootuser',
|
101
|
+
'rootPassword=rootpass123',
|
102
|
+
'buckets[0].name=metaflow-test',
|
103
|
+
'buckets[0].policy=none',
|
104
|
+
'buckets[0].purge=false',
|
105
|
+
'mode=standalone',
|
106
|
+
'replicas=1',
|
107
|
+
'persistence.enabled=false',
|
108
|
+
'resources.requests.memory=128Mi',
|
109
|
+
'resources.requests.cpu=50m',
|
110
|
+
'resources.limits.memory=256Mi',
|
111
|
+
'resources.limits.cpu=100m',
|
112
|
+
]
|
113
|
+
)
|
114
|
+
|
115
|
+
k8s_resource(
|
116
|
+
'minio',
|
117
|
+
port_forwards=[
|
118
|
+
'9000:9000',
|
119
|
+
'9001:9001'
|
120
|
+
],
|
121
|
+
links=[
|
122
|
+
link('http://localhost:9000', 'MinIO API'),
|
123
|
+
link('http://localhost:9001/login', 'MinIO Console (rootuser/rootpass123)')
|
124
|
+
],
|
125
|
+
labels=['minio'],
|
126
|
+
)
|
127
|
+
|
128
|
+
k8s_resource(
|
129
|
+
"minio-post-job",
|
130
|
+
labels=['minio'],
|
131
|
+
)
|
132
|
+
|
133
|
+
k8s_yaml(encode_yaml({
|
134
|
+
'apiVersion': 'v1',
|
135
|
+
'kind': 'Secret',
|
136
|
+
'metadata': {'name': 'minio-secret'},
|
137
|
+
'type': 'Opaque',
|
138
|
+
'stringData': {
|
139
|
+
'AWS_ACCESS_KEY_ID': 'rootuser',
|
140
|
+
'AWS_SECRET_ACCESS_KEY': 'rootpass123',
|
141
|
+
'AWS_ENDPOINT_URL_S3': 'http://minio.default.svc.cluster.local:9000',
|
142
|
+
}
|
143
|
+
}))
|
144
|
+
|
145
|
+
metaflow_config["METAFLOW_DEFAULT_DATASTORE"] = "s3"
|
146
|
+
metaflow_config["METAFLOW_DATASTORE_SYSROOT_S3"] = "s3://metaflow-test/metaflow"
|
147
|
+
metaflow_config["METAFLOW_KUBERNETES_SECRETS"] = "minio-secret"
|
148
|
+
|
149
|
+
aws_config = """[default]
|
150
|
+
aws_access_key_id = rootuser
|
151
|
+
aws_secret_access_key = rootpass123
|
152
|
+
endpoint_url = http://localhost:9000
|
153
|
+
"""
|
154
|
+
config_resources.append('minio')
|
155
|
+
|
156
|
+
#################################################
|
157
|
+
# POSTGRESQL
|
158
|
+
#################################################
|
159
|
+
if "postgresql" in enabled_components:
|
160
|
+
helm_remote(
|
161
|
+
'postgresql',
|
162
|
+
version='12.5.6',
|
163
|
+
repo_name='postgresql',
|
164
|
+
repo_url='https://charts.bitnami.com/bitnami',
|
165
|
+
set=[
|
166
|
+
'auth.username=metaflow',
|
167
|
+
'auth.password=metaflow123',
|
168
|
+
'auth.database=metaflow',
|
169
|
+
'primary.persistence.enabled=false',
|
170
|
+
'primary.resources.requests.memory=128Mi',
|
171
|
+
'primary.resources.requests.cpu=50m',
|
172
|
+
'primary.resources.limits.memory=256Mi',
|
173
|
+
'primary.resources.limits.cpu=100m',
|
174
|
+
'primary.terminationGracePeriodSeconds=1',
|
175
|
+
'primary.podSecurityContext.enabled=false',
|
176
|
+
'primary.containerSecurityContext.enabled=false',
|
177
|
+
'volumePermissions.enabled=false',
|
178
|
+
'shmVolume.enabled=false',
|
179
|
+
'primary.extraVolumes=null',
|
180
|
+
'primary.extraVolumeMounts=null'
|
181
|
+
]
|
182
|
+
)
|
183
|
+
|
184
|
+
k8s_resource(
|
185
|
+
'postgresql',
|
186
|
+
port_forwards=['5432:5432'],
|
187
|
+
links=[
|
188
|
+
link('postgresql://metaflow:metaflow@localhost:5432/metaflow', 'PostgreSQL Connection')
|
189
|
+
],
|
190
|
+
labels=['postgresql'],
|
191
|
+
resource_deps=components['postgresql'],
|
192
|
+
)
|
193
|
+
|
194
|
+
config_resources.append('postgresql')
|
195
|
+
|
196
|
+
#################################################
|
197
|
+
# ARGO WORKFLOWS
|
198
|
+
#################################################
|
199
|
+
if "argo-workflows" in enabled_components:
|
200
|
+
helm_remote(
|
201
|
+
'argo-workflows',
|
202
|
+
repo_name='argo',
|
203
|
+
repo_url='https://argoproj.github.io/argo-helm',
|
204
|
+
set=[
|
205
|
+
'server.extraArgs[0]=--auth-mode=server',
|
206
|
+
'workflow.serviceAccount.create=true',
|
207
|
+
'workflow.rbac.create=true',
|
208
|
+
'server.livenessProbe.initialDelaySeconds=1',
|
209
|
+
'server.readinessProbe.initialDelaySeconds=1',
|
210
|
+
'server.resources.requests.memory=128Mi',
|
211
|
+
'server.resources.requests.cpu=50m',
|
212
|
+
'server.resources.limits.memory=256Mi',
|
213
|
+
'server.resources.limits.cpu=100m',
|
214
|
+
'controller.resources.requests.memory=128Mi',
|
215
|
+
'controller.resources.requests.cpu=50m',
|
216
|
+
'controller.resources.limits.memory=256Mi',
|
217
|
+
'controller.resources.limits.cpu=100m'
|
218
|
+
]
|
219
|
+
)
|
220
|
+
|
221
|
+
k8s_yaml(encode_yaml({
|
222
|
+
'apiVersion': 'rbac.authorization.k8s.io/v1',
|
223
|
+
'kind': 'Role',
|
224
|
+
'metadata': {
|
225
|
+
'name': 'argo-workflowtaskresults-role',
|
226
|
+
'namespace': 'default'
|
227
|
+
},
|
228
|
+
'rules': [{
|
229
|
+
'apiGroups': ['argoproj.io'],
|
230
|
+
'resources': ['workflowtaskresults'],
|
231
|
+
'verbs': ['create', 'patch', 'get', 'list']
|
232
|
+
}]
|
233
|
+
}))
|
234
|
+
|
235
|
+
k8s_yaml(encode_yaml({
|
236
|
+
'apiVersion': 'rbac.authorization.k8s.io/v1',
|
237
|
+
'kind': 'RoleBinding',
|
238
|
+
'metadata': {
|
239
|
+
'name': 'default-argo-workflowtaskresults-binding',
|
240
|
+
'namespace': 'default'
|
241
|
+
},
|
242
|
+
'subjects': [{
|
243
|
+
'kind': 'ServiceAccount',
|
244
|
+
'name': 'default',
|
245
|
+
'namespace': 'default'
|
246
|
+
}],
|
247
|
+
'roleRef': {
|
248
|
+
'kind': 'Role',
|
249
|
+
'name': 'argo-workflowtaskresults-role',
|
250
|
+
'apiGroup': 'rbac.authorization.k8s.io'
|
251
|
+
}
|
252
|
+
}))
|
253
|
+
|
254
|
+
k8s_resource(
|
255
|
+
workload='argo-workflows-server',
|
256
|
+
port_forwards=['2746:2746'],
|
257
|
+
links=[
|
258
|
+
link('http://localhost:2746', 'Argo Workflows UI')
|
259
|
+
],
|
260
|
+
labels=['argo-workflows'],
|
261
|
+
resource_deps=components['argo-workflows']
|
262
|
+
)
|
263
|
+
|
264
|
+
k8s_resource(
|
265
|
+
workload='argo-workflows-workflow-controller',
|
266
|
+
labels=['argo-workflows'],
|
267
|
+
resource_deps=components['argo-workflows']
|
268
|
+
)
|
269
|
+
|
270
|
+
config_resources.append('argo-workflows-workflow-controller')
|
271
|
+
config_resources.append('argo-workflows-server')
|
272
|
+
|
273
|
+
#################################################
|
274
|
+
# ARGO EVENTS
|
275
|
+
#################################################
|
276
|
+
if "argo-events" in enabled_components:
|
277
|
+
helm_remote(
|
278
|
+
'argo-events',
|
279
|
+
repo_name='argo',
|
280
|
+
repo_url='https://argoproj.github.io/argo-helm',
|
281
|
+
set=[
|
282
|
+
'crds.install=true',
|
283
|
+
'controller.metrics.enabled=true',
|
284
|
+
'controller.livenessProbe.initialDelaySeconds=1',
|
285
|
+
'controller.readinessProbe.initialDelaySeconds=1',
|
286
|
+
'controller.resources.requests.memory=64Mi',
|
287
|
+
'controller.resources.requests.cpu=25m',
|
288
|
+
'controller.resources.limits.memory=128Mi',
|
289
|
+
'controller.resources.limits.cpu=50m',
|
290
|
+
'configs.jetstream.streamConfig.maxAge=72h',
|
291
|
+
'configs.jetstream.streamConfig.replicas=1',
|
292
|
+
'controller.rbac.enabled=true',
|
293
|
+
'controller.rbac.namespaced=false',
|
294
|
+
'controller.serviceAccount.create=true',
|
295
|
+
'controller.serviceAccount.name=argo-events-events-controller-sa',
|
296
|
+
'configs.jetstream.versions[0].configReloaderImage=natsio/nats-server-config-reloader:latest',
|
297
|
+
'configs.jetstream.versions[0].metricsExporterImage=natsio/prometheus-nats-exporter:latest',
|
298
|
+
'configs.jetstream.versions[0].natsImage=nats:latest',
|
299
|
+
'configs.jetstream.versions[0].startCommand=/nats-server',
|
300
|
+
'configs.jetstream.versions[0].version=latest',
|
301
|
+
'configs.jetstream.versions[1].configReloaderImage=natsio/nats-server-config-reloader:latest',
|
302
|
+
'configs.jetstream.versions[1].metricsExporterImage=natsio/prometheus-nats-exporter:latest',
|
303
|
+
'configs.jetstream.versions[1].natsImage=nats:2.9.15',
|
304
|
+
'configs.jetstream.versions[1].startCommand=/nats-server',
|
305
|
+
'configs.jetstream.versions[1].version=2.9.15',
|
306
|
+
]
|
307
|
+
)
|
308
|
+
|
309
|
+
k8s_yaml(encode_yaml({
|
310
|
+
'apiVersion': 'v1',
|
311
|
+
'kind': 'ServiceAccount',
|
312
|
+
'metadata': {
|
313
|
+
'name': 'operate-workflow-sa',
|
314
|
+
'namespace': 'default'
|
315
|
+
}
|
316
|
+
}))
|
317
|
+
|
318
|
+
k8s_yaml(encode_yaml({
|
319
|
+
'apiVersion': 'rbac.authorization.k8s.io/v1',
|
320
|
+
'kind': 'Role',
|
321
|
+
'metadata': {
|
322
|
+
'name': 'operate-workflow-role',
|
323
|
+
'namespace': 'default'
|
324
|
+
},
|
325
|
+
'rules': [{
|
326
|
+
'apiGroups': ['argoproj.io'],
|
327
|
+
'resources': [
|
328
|
+
'workflows',
|
329
|
+
'workflowtemplates',
|
330
|
+
'cronworkflows',
|
331
|
+
'clusterworkflowtemplates'
|
332
|
+
],
|
333
|
+
'verbs': ['*']
|
334
|
+
}]
|
335
|
+
}))
|
336
|
+
|
337
|
+
k8s_yaml(encode_yaml({
|
338
|
+
'apiVersion': 'rbac.authorization.k8s.io/v1',
|
339
|
+
'kind': 'RoleBinding',
|
340
|
+
'metadata': {
|
341
|
+
'name': 'operate-workflow-role-binding',
|
342
|
+
'namespace': 'default'
|
343
|
+
},
|
344
|
+
'roleRef': {
|
345
|
+
'apiGroup': 'rbac.authorization.k8s.io',
|
346
|
+
'kind': 'Role',
|
347
|
+
'name': 'operate-workflow-role'
|
348
|
+
},
|
349
|
+
'subjects': [{
|
350
|
+
'kind': 'ServiceAccount',
|
351
|
+
'name': 'operate-workflow-sa'
|
352
|
+
}]
|
353
|
+
}))
|
354
|
+
|
355
|
+
k8s_yaml(encode_yaml({
|
356
|
+
'apiVersion': 'rbac.authorization.k8s.io/v1',
|
357
|
+
'kind': 'Role',
|
358
|
+
'metadata': {
|
359
|
+
'name': 'view-events-role',
|
360
|
+
'namespace': 'default'
|
361
|
+
},
|
362
|
+
'rules': [{
|
363
|
+
'apiGroups': ['argoproj.io'],
|
364
|
+
'resources': [
|
365
|
+
'eventsources',
|
366
|
+
'eventbuses',
|
367
|
+
'sensors'
|
368
|
+
],
|
369
|
+
'verbs': [
|
370
|
+
'get',
|
371
|
+
'list',
|
372
|
+
'watch'
|
373
|
+
]
|
374
|
+
}]
|
375
|
+
}))
|
376
|
+
|
377
|
+
k8s_yaml(encode_yaml({
|
378
|
+
'apiVersion': 'rbac.authorization.k8s.io/v1',
|
379
|
+
'kind': 'RoleBinding',
|
380
|
+
'metadata': {
|
381
|
+
'name': 'view-events-role-binding',
|
382
|
+
'namespace': 'default'
|
383
|
+
},
|
384
|
+
'roleRef': {
|
385
|
+
'apiGroup': 'rbac.authorization.k8s.io',
|
386
|
+
'kind': 'Role',
|
387
|
+
'name': 'view-events-role'
|
388
|
+
},
|
389
|
+
'subjects': [{
|
390
|
+
'kind': 'ServiceAccount',
|
391
|
+
'name': 'argo-workflows',
|
392
|
+
'namespace': 'default'
|
393
|
+
}]
|
394
|
+
}))
|
395
|
+
|
396
|
+
k8s_yaml(encode_yaml({
|
397
|
+
'apiVersion': 'argoproj.io/v1alpha1',
|
398
|
+
'kind': 'EventBus',
|
399
|
+
'metadata': {
|
400
|
+
'name': 'default',
|
401
|
+
'namespace': 'default'
|
402
|
+
},
|
403
|
+
'spec': {
|
404
|
+
'jetstream': {
|
405
|
+
'version': '2.9.15',
|
406
|
+
'replicas': 3,
|
407
|
+
'containerTemplate': {
|
408
|
+
'resources': {
|
409
|
+
'limits': {
|
410
|
+
'cpu': '100m',
|
411
|
+
'memory': '128Mi'
|
412
|
+
},
|
413
|
+
'requests': {
|
414
|
+
'cpu': '100m',
|
415
|
+
'memory': '128Mi'
|
416
|
+
}
|
417
|
+
}
|
418
|
+
}
|
419
|
+
}
|
420
|
+
}
|
421
|
+
}))
|
422
|
+
|
423
|
+
k8s_yaml(encode_yaml({
|
424
|
+
'apiVersion': 'argoproj.io/v1alpha1',
|
425
|
+
'kind': 'EventSource',
|
426
|
+
'metadata': {
|
427
|
+
'name': 'argo-events-webhook',
|
428
|
+
'namespace': 'default'
|
429
|
+
},
|
430
|
+
'spec': {
|
431
|
+
'template': {
|
432
|
+
'container': {
|
433
|
+
'resources': {
|
434
|
+
'requests': {
|
435
|
+
'cpu': '25m',
|
436
|
+
'memory': '50Mi'
|
437
|
+
},
|
438
|
+
'limits': {
|
439
|
+
'cpu': '25m',
|
440
|
+
'memory': '50Mi'
|
441
|
+
}
|
442
|
+
}
|
443
|
+
}
|
444
|
+
},
|
445
|
+
'service': {
|
446
|
+
'ports': [
|
447
|
+
{
|
448
|
+
'port': 12000,
|
449
|
+
'targetPort': 12000
|
450
|
+
}
|
451
|
+
]
|
452
|
+
},
|
453
|
+
'webhook': {
|
454
|
+
'metaflow-event': {
|
455
|
+
'port': '12000',
|
456
|
+
'endpoint': '/metaflow-event',
|
457
|
+
'method': 'POST'
|
458
|
+
}
|
459
|
+
}
|
460
|
+
}
|
461
|
+
}))
|
462
|
+
|
463
|
+
# Create a custom service and port-forward it because tilt :/
|
464
|
+
k8s_yaml(encode_yaml(
|
465
|
+
{
|
466
|
+
'apiVersion': 'v1',
|
467
|
+
'kind': 'Service',
|
468
|
+
'metadata': {
|
469
|
+
'name': 'argo-events-webhook-eventsource-svc-tilt',
|
470
|
+
'namespace': 'default',
|
471
|
+
},
|
472
|
+
'spec': {
|
473
|
+
'ports': [{
|
474
|
+
'port': 12000,
|
475
|
+
'protocol': 'TCP',
|
476
|
+
'targetPort': 12000
|
477
|
+
}],
|
478
|
+
'selector': {
|
479
|
+
'controller': 'eventsource-controller',
|
480
|
+
'eventsource-name': 'argo-events-webhook',
|
481
|
+
'owner-name': 'argo-events-webhook'
|
482
|
+
},
|
483
|
+
'type': 'ClusterIP'
|
484
|
+
}
|
485
|
+
}
|
486
|
+
))
|
487
|
+
|
488
|
+
local_resource(
|
489
|
+
name='argo-events-webhook-eventsource-svc',
|
490
|
+
serve_cmd='while ! kubectl get service/argo-events-webhook-eventsource-svc-tilt >/dev/null 2>&1 || ! kubectl get pods -l eventsource-name=argo-events-webhook -o jsonpath="{.items[*].status.phase}" | grep -q "Running"; do sleep 5; done && kubectl port-forward service/argo-events-webhook-eventsource-svc-tilt 12000:12000',
|
491
|
+
links=[
|
492
|
+
link('http://localhost:12000/metaflow-event', 'Argo Events Webhook'),
|
493
|
+
],
|
494
|
+
labels=['argo-events']
|
495
|
+
)
|
496
|
+
|
497
|
+
k8s_resource(
|
498
|
+
'argo-events-controller-manager',
|
499
|
+
labels=['argo-events'],
|
500
|
+
)
|
501
|
+
|
502
|
+
metaflow_config["METAFLOW_ARGO_EVENTS_EVENT"] = "metaflow-event"
|
503
|
+
metaflow_config["METAFLOW_ARGO_EVENTS_EVENT_BUS"] = "default"
|
504
|
+
metaflow_config["METAFLOW_ARGO_EVENTS_EVENT_SOURCE"] = "argo-events-webhook"
|
505
|
+
metaflow_config["METAFLOW_ARGO_EVENTS_SERVICE_ACCOUNT"] = "operate-workflow-sa"
|
506
|
+
metaflow_config["METAFLOW_ARGO_EVENTS_WEBHOOK_AUTH"] = "service"
|
507
|
+
metaflow_config["METAFLOW_ARGO_EVENTS_WEBHOOK_URL"] = "http://argo-events-webhook-eventsource-svc:12000/metaflow-event"
|
508
|
+
|
509
|
+
config_resources.append('argo-events-controller-manager')
|
510
|
+
config_resources.append('argo-events-webhook-eventsource-svc')
|
511
|
+
|
512
|
+
#################################################
|
513
|
+
# METADATA SERVICE
|
514
|
+
#################################################
|
515
|
+
if "metadata-service" in enabled_components:
|
516
|
+
helm_remote(
|
517
|
+
'metaflow-service',
|
518
|
+
repo_name='metaflow-tools',
|
519
|
+
repo_url='https://outerbounds.github.io/metaflow-tools',
|
520
|
+
set=[
|
521
|
+
'metadatadb.user=metaflow',
|
522
|
+
'metadatadb.password=metaflow123',
|
523
|
+
'metadatadb.database=metaflow',
|
524
|
+
'metadatadb.host=postgresql',
|
525
|
+
'image.repository=public.ecr.aws/p7g1e3j4/metaflow-service',
|
526
|
+
'image.tag=2.4.13-fbcc7d04',
|
527
|
+
'resources.requests.cpu=25m',
|
528
|
+
'resources.requests.memory=64Mi',
|
529
|
+
'resources.limits.cpu=50m',
|
530
|
+
'resources.limits.memory=128Mi'
|
531
|
+
]
|
532
|
+
)
|
533
|
+
|
534
|
+
k8s_resource(
|
535
|
+
'metaflow-service',
|
536
|
+
port_forwards=['8080:8080'],
|
537
|
+
links=[link('http://localhost:8080/ping', 'Ping Metaflow Service')],
|
538
|
+
labels=['metadata-service'],
|
539
|
+
resource_deps=components['metadata-service']
|
540
|
+
)
|
541
|
+
|
542
|
+
metaflow_config["METAFLOW_DEFAULT_METADATA"] = "service"
|
543
|
+
metaflow_config["METAFLOW_SERVICE_URL"] = "http://localhost:8080"
|
544
|
+
metaflow_config["METAFLOW_SERVICE_INTERNAL_URL"] = "http://metaflow-service.default.svc.cluster.local:8080"
|
545
|
+
|
546
|
+
config_resources.append('metaflow-service')
|
547
|
+
|
548
|
+
#################################################
|
549
|
+
# METAFLOW UI
|
550
|
+
#################################################
|
551
|
+
if "ui" in enabled_components:
|
552
|
+
helm_remote(
|
553
|
+
'metaflow-ui',
|
554
|
+
repo_name='metaflow-tools',
|
555
|
+
repo_url='https://outerbounds.github.io/metaflow-tools',
|
556
|
+
set=[
|
557
|
+
'uiBackend.metadatadb.user=metaflow',
|
558
|
+
'uiBackend.metadatadb.password=metaflow123',
|
559
|
+
'uiBackend.metadatadb.name=metaflow',
|
560
|
+
'uiBackend.metadatadb.host=postgresql',
|
561
|
+
'uiBackend.metaflowDatastoreSysRootS3=s3://metaflow-test',
|
562
|
+
'uiBackend.metaflowS3EndpointURL=http://minio.default.svc.cluster.local:9000',
|
563
|
+
'uiBackend.image.name=public.ecr.aws/p7g1e3j4/metaflow-service',
|
564
|
+
'uiBackend.image.tag=2.4.13-fbcc7d04',
|
565
|
+
'uiBackend.env[0].name=AWS_ACCESS_KEY_ID',
|
566
|
+
'uiBackend.env[0].value=rootuser',
|
567
|
+
'uiBackend.env[1].name=AWS_SECRET_ACCESS_KEY',
|
568
|
+
'uiBackend.env[1].value=rootpass123',
|
569
|
+
# TODO: configure lower cache limits
|
570
|
+
'uiBackend.resources.requests.cpu=100m',
|
571
|
+
'uiBackend.resources.requests.memory=256Mi',
|
572
|
+
'uiStatic.metaflowUIBackendURL=http://localhost:8083/api',
|
573
|
+
'uiStatic.image.name=public.ecr.aws/outerbounds/metaflow_ui',
|
574
|
+
'uiStatic.image.tag=v1.3.13-5-g5dd049e',
|
575
|
+
'uiStatic.resources.requests.cpu=25m',
|
576
|
+
'uiStatic.resources.requests.memory=64Mi',
|
577
|
+
'uiStatic.resources.limits.cpu=50m',
|
578
|
+
'uiStatic.resources.limits.memory=128Mi',
|
579
|
+
]
|
580
|
+
)
|
581
|
+
|
582
|
+
k8s_resource(
|
583
|
+
'metaflow-ui-static',
|
584
|
+
port_forwards=['3000:3000'],
|
585
|
+
links=[link('http://localhost:3000', 'Metaflow UI')],
|
586
|
+
labels=['metaflow-ui'],
|
587
|
+
resource_deps=components['ui']
|
588
|
+
)
|
589
|
+
|
590
|
+
k8s_resource(
|
591
|
+
'metaflow-ui',
|
592
|
+
port_forwards=['8083:8083'],
|
593
|
+
links=[link('http://localhost:3000', 'Metaflow UI')],
|
594
|
+
labels=['metaflow-ui'],
|
595
|
+
resource_deps=components['ui']
|
596
|
+
)
|
597
|
+
|
598
|
+
metaflow_config["METAFLOW_UI_URL"] = "http://localhost:3000"
|
599
|
+
|
600
|
+
config_resources.append('metaflow-ui')
|
601
|
+
config_resources.append('metaflow-ui-static')
|
602
|
+
|
603
|
+
local_resource(
|
604
|
+
name="generate-configs",
|
605
|
+
cmd=write_config_files(),
|
606
|
+
resource_deps=config_resources,
|
607
|
+
)
|
@@ -0,0 +1,104 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
COLOR="214"
|
6
|
+
|
7
|
+
LOGO="
|
8
|
+
______ ________________________________________ __________ __
|
9
|
+
___ |/ /__ ____/__ __/__ |__ ____/__ / __ __ \_ | / /
|
10
|
+
__ /|_/ /__ __/ __ / __ /| |_ /_ __ / _ / / /_ | /| / /
|
11
|
+
_ / / / _ /___ _ / _ ___ | __/ _ /___/ /_/ /__ |/ |/ /
|
12
|
+
/_/ /_/ /_____/ /_/ /_/ |_/_/ /_____/\____/ ____/|__/
|
13
|
+
"
|
14
|
+
|
15
|
+
SERVICE_OPTIONS=(
|
16
|
+
"minio"
|
17
|
+
"metadata-service"
|
18
|
+
"ui"
|
19
|
+
"argo-workflows"
|
20
|
+
"argo-events"
|
21
|
+
)
|
22
|
+
|
23
|
+
gum style "$LOGO" \
|
24
|
+
--foreground "$COLOR" \
|
25
|
+
--padding "0 1" \
|
26
|
+
--margin "0 1" \
|
27
|
+
--align center >&2
|
28
|
+
|
29
|
+
gum style "Select services to deploy (press enter to select all):" \
|
30
|
+
--foreground "$COLOR" \
|
31
|
+
--bold >&2
|
32
|
+
|
33
|
+
pretty_print() {
|
34
|
+
local items=("$@")
|
35
|
+
|
36
|
+
if [ "${#items[@]}" -eq 1 ]; then
|
37
|
+
echo "${items[0]}"
|
38
|
+
return
|
39
|
+
fi
|
40
|
+
|
41
|
+
if [ "${#items[@]}" -eq 2 ]; then
|
42
|
+
echo "${items[0]} and ${items[1]}"
|
43
|
+
return
|
44
|
+
fi
|
45
|
+
|
46
|
+
local last_item="${items[-1]}"
|
47
|
+
unset 'items[-1]'
|
48
|
+
echo "$(IFS=,; echo "${items[*]}"), and $last_item"
|
49
|
+
}
|
50
|
+
|
51
|
+
pretty_print() {
|
52
|
+
local items=("$@")
|
53
|
+
local length=${#items[@]}
|
54
|
+
|
55
|
+
if [ "$length" -eq 0 ]; then
|
56
|
+
echo "(none)"
|
57
|
+
return
|
58
|
+
fi
|
59
|
+
|
60
|
+
if [ "$length" -eq 1 ]; then
|
61
|
+
echo "${items[0]}"
|
62
|
+
return
|
63
|
+
fi
|
64
|
+
|
65
|
+
if [ "$length" -eq 2 ]; then
|
66
|
+
echo "${items[0]} and ${items[1]}"
|
67
|
+
return
|
68
|
+
fi
|
69
|
+
|
70
|
+
local last_index=$((length - 1))
|
71
|
+
local last_item="${items[$last_index]}"
|
72
|
+
unset 'items[last_index]'
|
73
|
+
|
74
|
+
local joined
|
75
|
+
IFS=","
|
76
|
+
joined="${items[*]}"
|
77
|
+
unset IFS
|
78
|
+
joined="${joined//,/, }"
|
79
|
+
|
80
|
+
echo "$joined, and $last_item"
|
81
|
+
}
|
82
|
+
|
83
|
+
SELECTED="$(
|
84
|
+
gum choose "${SERVICE_OPTIONS[@]}" \
|
85
|
+
--no-limit \
|
86
|
+
--cursor.foreground="$COLOR" \
|
87
|
+
--selected.foreground="$COLOR"
|
88
|
+
)"
|
89
|
+
|
90
|
+
SELECTED_SERVICES=()
|
91
|
+
while IFS= read -r line; do
|
92
|
+
[ -n "$line" ] && SELECTED_SERVICES+=("$line")
|
93
|
+
done <<< "$SELECTED"
|
94
|
+
|
95
|
+
# If nothing was chosen, default to all
|
96
|
+
if [ -z "$SELECTED_SERVICES" ]; then
|
97
|
+
gum style "🙅 No services selected. Deploying all..." --foreground "$COLOR" >&2
|
98
|
+
SELECTED_SERVICES=("${SERVICE_OPTIONS[@]}")
|
99
|
+
fi
|
100
|
+
|
101
|
+
PRINTABLE="$(pretty_print "${SELECTED_SERVICES[@]}")"
|
102
|
+
gum style "✅ Deploying $PRINTABLE" --foreground "$COLOR" >&2
|
103
|
+
|
104
|
+
echo "$(IFS=,; echo "${SELECTED_SERVICES[*]}")"
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: metaflow
|
3
|
-
Version: 2.
|
4
|
-
Summary: Metaflow: More
|
3
|
+
Version: 2.15.0
|
4
|
+
Summary: Metaflow: More AI and ML, Less Engineering
|
5
5
|
Author: Metaflow Developers
|
6
6
|
Author-email: help@metaflow.org
|
7
7
|
License: Apache Software License
|
@@ -26,7 +26,7 @@ License-File: LICENSE
|
|
26
26
|
Requires-Dist: requests
|
27
27
|
Requires-Dist: boto3
|
28
28
|
Provides-Extra: stubs
|
29
|
-
Requires-Dist: metaflow-stubs==2.
|
29
|
+
Requires-Dist: metaflow-stubs==2.15.0; extra == "stubs"
|
30
30
|
Dynamic: author
|
31
31
|
Dynamic: author-email
|
32
32
|
Dynamic: classifier
|
@@ -16,7 +16,7 @@ metaflow/includefile.py,sha256=kWKDSlzVcRVNGG9PV5eB3o2ynrzqhVsfaLtkqjshn7Q,20948
|
|
16
16
|
metaflow/info_file.py,sha256=wtf2_F0M6dgiUu74AFImM8lfy5RrUw5Yj7Rgs2swKRY,686
|
17
17
|
metaflow/integrations.py,sha256=LlsaoePRg03DjENnmLxZDYto3NwWc9z_PtU6nJxLldg,1480
|
18
18
|
metaflow/lint.py,sha256=x4p6tnRzYqNNniCGXyrUW0WuYfTUgnaOMRivxvnxask,11661
|
19
|
-
metaflow/metaflow_config.py,sha256=
|
19
|
+
metaflow/metaflow_config.py,sha256=jCyJhKrBePqygpfZ4C-gmU14FlTesvFmmimnTP3t_U8,23433
|
20
20
|
metaflow/metaflow_config_funcs.py,sha256=5GlvoafV6SxykwfL8D12WXSfwjBN_NsyuKE_Q3gjGVE,6738
|
21
21
|
metaflow/metaflow_current.py,sha256=pfkXmkyHeMJhxIs6HBJNBEaBDpcl5kz9Wx5mW6F_3qo,7164
|
22
22
|
metaflow/metaflow_environment.py,sha256=gs_UpYpuOKEEfFM0z0tnwje7zAVsQ5Ck7Dp2M9_1utQ,8065
|
@@ -36,7 +36,7 @@ metaflow/tuple_util.py,sha256=_G5YIEhuugwJ_f6rrZoelMFak3DqAR2tt_5CapS1XTY,830
|
|
36
36
|
metaflow/unbounded_foreach.py,sha256=p184WMbrMJ3xKYHwewj27ZhRUsSj_kw1jlye5gA9xJk,387
|
37
37
|
metaflow/util.py,sha256=mJBkV5tShIyCsLDeM1zygQGeciQVMrVPm_qI8Oi33G0,14656
|
38
38
|
metaflow/vendor.py,sha256=FchtA9tH22JM-eEtJ2c9FpUdMn8sSb1VHuQS56EcdZk,5139
|
39
|
-
metaflow/version.py,sha256=
|
39
|
+
metaflow/version.py,sha256=IWpJOWnkdfrf92MEtc6EPVbrvSldtZ2YIiIqxV_gwJI,28
|
40
40
|
metaflow/_vendor/__init__.py,sha256=y_CiwUD3l4eAKvTVDZeqgVujMy31cAM1qjAB-HfI-9s,353
|
41
41
|
metaflow/_vendor/typing_extensions.py,sha256=0nUs5p1A_UrZigrAVBoOEM6TxU37zzPDUtiij1ZwpNc,110417
|
42
42
|
metaflow/_vendor/zipp.py,sha256=ajztOH-9I7KA_4wqDYygtHa6xUBVZgFpmZ8FE74HHHI,8425
|
@@ -122,6 +122,7 @@ metaflow/client/filecache.py,sha256=Wy0yhhCqC1JZgebqi7z52GCwXYnkAqMZHTtxThvwBgM,
|
|
122
122
|
metaflow/cmd/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
123
123
|
metaflow/cmd/configure_cmd.py,sha256=o-DKnUf2FBo_HiMVyoyzQaGBSMtpbEPEdFTQZ0hkU-k,33396
|
124
124
|
metaflow/cmd/main_cli.py,sha256=H0UC-jiZjThHZgQeMyNZh3raSDDyUTvMspYUqKFnNSU,2955
|
125
|
+
metaflow/cmd/make_wrapper.py,sha256=NFpSdESs4Ks9xeurmYB5VUyYplhNcONDZJcUP2cf8-8,494
|
125
126
|
metaflow/cmd/tutorials_cmd.py,sha256=8FdlKkicTOhCIDKcBR5b0Oz6giDvS-EMY3o9skIrRqw,5156
|
126
127
|
metaflow/cmd/util.py,sha256=jS_0rUjOnGGzPT65fzRLdGjrYAOOLA4jU2S0HJLV0oc,406
|
127
128
|
metaflow/cmd/develop/__init__.py,sha256=p1Sy8yU1MEKSrH5ttOWOZvNcI1qYu6J6jghdTHwPgOw,689
|
@@ -194,9 +195,9 @@ metaflow/plugins/aws/aws_client.py,sha256=mO8UD6pxFaOnxDb3hTP3HB7Gqb_ZxoR-76LT68
|
|
194
195
|
metaflow/plugins/aws/aws_utils.py,sha256=kNd61C54Y3WxrL7KSjoKydRjBQ1p3exc9QXux-jZyDE,7510
|
195
196
|
metaflow/plugins/aws/batch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
196
197
|
metaflow/plugins/aws/batch/batch.py,sha256=e9ssahWM18GnipPK2sqYB-ztx9w7Eoo7YtWyEtufYxs,17787
|
197
|
-
metaflow/plugins/aws/batch/batch_cli.py,sha256=
|
198
|
+
metaflow/plugins/aws/batch/batch_cli.py,sha256=aRLuLky0xLGU5zR8jqUQQ0Fbs9o5Wq4Z4M8MLF9XSSw,11807
|
198
199
|
metaflow/plugins/aws/batch/batch_client.py,sha256=J50RMEXeEXFe5RqNUM1HN22BuDQFYFVQ4FSMOK55VWY,28798
|
199
|
-
metaflow/plugins/aws/batch/batch_decorator.py,sha256=
|
200
|
+
metaflow/plugins/aws/batch/batch_decorator.py,sha256=Ks2boTyseI0ohN1ecwD2qWZx_YeERRXTSjbeughVBpc,17878
|
200
201
|
metaflow/plugins/aws/secrets_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
201
202
|
metaflow/plugins/aws/secrets_manager/aws_secrets_manager_secrets_provider.py,sha256=bBrGw4gRcKX9SLD8iKqPm_S_Zw5Y6F8AjxP6jPbkPpI,8136
|
202
203
|
metaflow/plugins/aws/step_functions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -300,7 +301,7 @@ metaflow/plugins/metadata_providers/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uz
|
|
300
301
|
metaflow/plugins/metadata_providers/local.py,sha256=Z0CXaGZJbAkj4II3WspJi-uCCtShH64yaXZQ5i9Ym7g,24390
|
301
302
|
metaflow/plugins/metadata_providers/service.py,sha256=K0Ym6lcmegX6wBC5uZbeAFQJSDFc8e6DzJiCB1VIqjc,22554
|
302
303
|
metaflow/plugins/pypi/__init__.py,sha256=0YFZpXvX7HCkyBFglatual7XGifdA1RwC3U4kcizyak,1037
|
303
|
-
metaflow/plugins/pypi/bootstrap.py,sha256=
|
304
|
+
metaflow/plugins/pypi/bootstrap.py,sha256=XAz832qSLFxIXW6SP02N8PQ_7CKiqrCfirkE80Iwarc,14881
|
304
305
|
metaflow/plugins/pypi/conda_decorator.py,sha256=piFcE4uGmWhhbGlxMK0GHd7BGEyqy6r9BFy8Mjoi80Q,15937
|
305
306
|
metaflow/plugins/pypi/conda_environment.py,sha256=d5BAiY_aJJdlJ5h3N5nGSDmVoOY-8BVKqEbA5nrCpCY,22113
|
306
307
|
metaflow/plugins/pypi/micromamba.py,sha256=LLJ2dGGOEyld07W8iI6dtE01h2Y1PQnBhU-dMBssZ3c,16502
|
@@ -318,7 +319,7 @@ metaflow/runner/deployer_impl.py,sha256=Kab9rLoA3EiBJDtTTulhPCeKzqiljW366nx2Tm0L
|
|
318
319
|
metaflow/runner/metaflow_runner.py,sha256=L302ew_BPBPs-NnW8n92dqqbqmHwrwGL5D6kTZvl5vY,16074
|
319
320
|
metaflow/runner/nbdeploy.py,sha256=Sp5w-6nCZwjHaRBHWxi8udya-RYnJOB76KNLjB4L7Gs,4166
|
320
321
|
metaflow/runner/nbrun.py,sha256=LhJu-Teoi7wTkNxg0kpNPVXFxH_9P4lvtp0ysMEIFJ8,7299
|
321
|
-
metaflow/runner/subprocess_manager.py,sha256=
|
322
|
+
metaflow/runner/subprocess_manager.py,sha256=vqrOgRAtQYfTEBFFF7iRzrqbhFaVTRZohms4Kt7jxJA,22300
|
322
323
|
metaflow/runner/utils.py,sha256=jC-Z5xzGEEa6Qc71U_5r1wHsS-qYV7-czv1BO-q2MSs,10213
|
323
324
|
metaflow/sidecar/__init__.py,sha256=1mmNpmQ5puZCpRmmYlCOeieZ4108Su9XQ4_EqF1FGOU,131
|
324
325
|
metaflow/sidecar/sidecar.py,sha256=EspKXvPPNiyRToaUZ51PS5TT_PzrBNAurn_wbFnmGr0,1334
|
@@ -360,9 +361,12 @@ metaflow/user_configs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
|
|
360
361
|
metaflow/user_configs/config_decorators.py,sha256=qCKVAvd0NKgaCxQ2OThes5-DYHXq6A1HqURubYNeFdw,20481
|
361
362
|
metaflow/user_configs/config_options.py,sha256=m6jccSpzI4qUJ7vyYkYBIf8G3V0Caunxg_k7zg4Zlqg,21067
|
362
363
|
metaflow/user_configs/config_parameters.py,sha256=oeJGVKu1ao_YQX6Lg6P2FEv5k5-_F4sARLlVpTW9ezM,15502
|
363
|
-
metaflow-2.
|
364
|
-
metaflow-2.
|
365
|
-
metaflow-2.
|
366
|
-
metaflow-2.
|
367
|
-
metaflow-2.
|
368
|
-
metaflow-2.
|
364
|
+
metaflow-2.15.0.data/data/share/metaflow/devtools/Makefile,sha256=x9Q2FsScc9XQa0uVV2oNpA3VHwet_6oc8aQN0ztbM2Q,12907
|
365
|
+
metaflow-2.15.0.data/data/share/metaflow/devtools/Tiltfile,sha256=ednswaJXxyH4wRWPNQZMzb5Kg1TiukHUNXgUh_DP8mU,20016
|
366
|
+
metaflow-2.15.0.data/data/share/metaflow/devtools/pick_services.sh,sha256=DCnrMXwtApfx3B4S-YiZESMyAFHbXa3VuNL0MxPLyiE,2196
|
367
|
+
metaflow-2.15.0.dist-info/LICENSE,sha256=nl_Lt5v9VvJ-5lWJDT4ddKAG-VZ-2IaLmbzpgYDz2hU,11343
|
368
|
+
metaflow-2.15.0.dist-info/METADATA,sha256=cvzxosgu6SxOBgmkE_UHfdyJEIkvadf54EsYe3npi8k,6118
|
369
|
+
metaflow-2.15.0.dist-info/WHEEL,sha256=3HfeesdN7jshHPzN8HJ8UeFRlEd6ApplqndzbPTvPl8,109
|
370
|
+
metaflow-2.15.0.dist-info/entry_points.txt,sha256=RvEq8VFlgGe_FfqGOZi0D7ze1hLD0pAtXeNyGfzc_Yc,103
|
371
|
+
metaflow-2.15.0.dist-info/top_level.txt,sha256=v1pDHoWaSaKeuc5fKTRSfsXCKSdW1zvNVmvA-i0if3o,9
|
372
|
+
metaflow-2.15.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|