Skip to content

Commit 9357864

Browse files
authored
upload(wasm): allow uploading workflows defined inside containers (#88)
1 parent 6eefd94 commit 9357864

File tree

6 files changed

+70
-4
lines changed

6 files changed

+70
-4
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ running [Faasm](https://github.com/faasm/faasm) cluster.
88
To install `faasmctl` you need a working `pip` (virtual-)environment. Then:
99

1010
```bash
11-
pip install faasmctl==0.44.0
11+
pip install faasmctl==0.45.0
1212
```
1313

1414
## Usage

faasmctl/tasks/upload.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from faasmctl.util.upload import upload_file, upload_wasm
22
from invoke import task
3+
from os.path import join
4+
from subprocess import run
35

46

57
@task(default=True)
@@ -17,6 +19,37 @@ def wasm(ctx, user, func, wasm_file, ini_file=None):
1719
upload_wasm(user, func, wasm_file, ini_file)
1820

1921

22+
@task
23+
def workflow(ctx, wflow, path, ini_file=None):
24+
"""
25+
Upload all WASM files corresponding to a workflow (from --path)
26+
27+
Path indicates a directory where each function in the workflow is in a
28+
different sub-directory, in a single WASM file. Uploading a workflow is
29+
equivalent to uplodaing a `user` in the traditional Faasm sense. Note that
30+
you may prefix the path with a container name, followed by a colon, and
31+
then the path, to copy the file from a path inside a container.
32+
"""
33+
wasm_in_ctr = path.rfind(":") != -1
34+
if wasm_in_ctr:
35+
ctr_image = path[: path.rfind(":")]
36+
in_ctr_path = path[path.rfind(":") + 1 :]
37+
docker_cmd = "docker run --rm -it {} ls --format=commas {}".format(
38+
ctr_image, in_ctr_path
39+
)
40+
funcs = (
41+
run(docker_cmd, shell=True, capture_output=True)
42+
.stdout.decode("utf-8")
43+
.strip()
44+
.split(", ")
45+
)
46+
47+
for func in funcs:
48+
upload_wasm(wflow, func, join(path, func, "function.wasm"))
49+
else:
50+
raise RuntimeError("Not implemented!")
51+
52+
2053
@task()
2154
def file(ctx, host_path, faasm_path, ini_file=None):
2255
"""

faasmctl/util/compose.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from subprocess import run
1212
from time import sleep
1313

14+
DEFAULT_FAASM_CAPTURE_STDOUT = "on"
1415
DEFAULT_FAASM_OVERRIDE_CPU_COUNT = "8"
1516

1617

@@ -114,6 +115,10 @@ def get_compose_env_vars(faasm_checkout, mount_source, ini_file=None):
114115
if "FAASM_OVERRIDE_CPU_COUNT" in environ:
115116
env["FAASM_OVERRIDE_CPU_COUNT"] = environ["FAASM_OVERRIDE_CPU_COUNT"]
116117

118+
env["FAASM_CAPTURE_STDOUT"] = DEFAULT_FAASM_CAPTURE_STDOUT
119+
if "FAASM_CAPTURE_STDOUT" in environ:
120+
env["FAASM_CAPTURE_STDOUT"] = environ["FAASM_CAPTURE_STDOUT"]
121+
117122
if "FAASM_CLI_IMAGE" in environ:
118123
env["FAASM_CLI_IMAGE"] = environ["FAASM_CLI_IMAGE"]
119124

faasmctl/util/upload.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
)
55
from faasmctl.util.docker import in_docker
66
from requests import put
7+
from subprocess import run
78

89

910
def upload_wasm(user, func, wasm_file, ini_file=None):
@@ -13,11 +14,38 @@ def upload_wasm(user, func, wasm_file, ini_file=None):
1314
if not ini_file:
1415
ini_file = get_faasm_ini_file()
1516

17+
# Work out if WASM file is a host path, or a path in a container
18+
wasm_in_ctr = wasm_file.rfind(":") != -1
19+
if wasm_in_ctr:
20+
tmp_ctr_name = "wasm-ctr"
21+
22+
def stop_ctr():
23+
run(f"docker rm -f {tmp_ctr_name}", shell=True, capture_output=True)
24+
25+
ctr_image = wasm_file[: wasm_file.rfind(":")]
26+
in_ctr_path = wasm_file[wasm_file.rfind(":") + 1 :]
27+
docker_cmd = "docker run -d --name {} {} bash".format(tmp_ctr_name, ctr_image)
28+
run(docker_cmd, shell=True, capture_output=True)
29+
30+
tmp_wasm_file = "/tmp/wasm-ctr-func.wasm"
31+
docker_cmd = "docker cp {}:{} {}".format(
32+
tmp_ctr_name, in_ctr_path, tmp_wasm_file
33+
)
34+
try:
35+
run(docker_cmd, shell=True, capture_output=True)
36+
except Exception as e:
37+
print("Caught exception copying: {}".format(e))
38+
39+
stop_ctr()
40+
41+
wasm_file = tmp_wasm_file
42+
1643
host, port = get_faasm_upload_host_port(ini_file, in_docker())
1744
url = "http://{}:{}/f/{}/{}".format(host, port, user, func)
1845

1946
response = put(url, data=open(wasm_file, "rb"))
20-
print("Response ({}): {}".format(response.status_code, response.text))
47+
if response.status_code != 200:
48+
raise RuntimeError(f"Error uploading WASM: {response.text}")
2149

2250

2351
def upload_python(func, python_file, ini_file=None):

faasmctl/util/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FAASMCTL_VERSION = "0.44.0"
1+
FAASMCTL_VERSION = "0.45.0"
22

33

44
def get_version():

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "faasmctl"
7-
version = "0.44.0"
7+
version = "0.45.0"
88
authors = [
99
{ name="Faasm Team", email="[email protected]" },
1010
]

0 commit comments

Comments
 (0)