-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathtasks.py
132 lines (101 loc) · 4 KB
/
tasks.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
from configparser import ConfigParser
from contextlib import suppress
from pathlib import Path
from invoke import Context, task
from invoke.exceptions import UnexpectedExit
from brewblox_devcon_spark.models import FirmwareConfig
ROOT = Path(__file__).parent.resolve()
FW_BASE_URL = 'https://brewblox.blob.core.windows.net/firmware'
def get_fw_config() -> FirmwareConfig: # pragma: no cover
"""
Globally cached getter for firmware config.
When first called, config is parsed from the firmware.ini file.
"""
parser = ConfigParser()
parser.read(ROOT / 'firmware.ini')
raw = dict(parser['FIRMWARE'].items())
config = FirmwareConfig(**raw)
return config
@task
def compile_proto(ctx: Context):
out_dir = ROOT / 'brewblox_devcon_spark/codec/proto-compiled'
with ctx.cd(ROOT):
ctx.run('uv sync')
ctx.run(f'rm -rf {out_dir}/*_pb2.py')
ctx.run(
' '.join(
[
'python3 -m grpc_tools.protoc',
'-I=./brewblox-proto/proto',
f'--python_out="{out_dir}"',
' ./brewblox-proto/proto/**.proto',
]
)
)
@task
def download_firmware(ctx: Context):
fw_config = get_fw_config()
fw_dir = ROOT / 'firmware'
fw_date = fw_config.firmware_date
fw_version = fw_config.firmware_version
fw_file = 'brewblox-release.tar.gz'
url = f'{FW_BASE_URL}/{fw_date}-{fw_version}/{fw_file}'
print(f'Downloading firmware release {fw_date}-{fw_version}')
with ctx.cd(ROOT):
# Clear firmware dir
ctx.run(f'mkdir -p {fw_dir}')
ctx.run(f'rm -rf {fw_dir}/*')
# Download and extract firmware files
ctx.run(f'curl -sSfO "{url}"')
ctx.run(f'tar -xzvf {fw_file} -C {fw_dir}')
ctx.run(f'rm {fw_file}')
# Simulators are executable files
ctx.run(f'chmod +x {fw_dir}/*.sim')
@task(post=[compile_proto, download_firmware])
def update_firmware(ctx: Context, release='develop'):
url = f'{FW_BASE_URL}/{release}/firmware.ini'
with ctx.cd(ROOT):
ctx.run(f'curl -sSf -o firmware.ini "{url}"')
fw_config = get_fw_config()
fw_date = fw_config.firmware_date
fw_version = fw_config.firmware_version
proto_sha = fw_config.proto_sha
print(f'Updating to firmware release {fw_date}-{fw_version}')
with ctx.cd(ROOT / 'brewblox-proto'):
ctx.run('git fetch')
ctx.run(f'git checkout --quiet "{proto_sha}"')
@task
def testclean(ctx: Context):
"""
Cleans up leftover test containers, networks, and simulators.
Container cleanup is normally done in test fixtures.
This is skipped if debugged tests are stopped halfway.
"""
result = ctx.run('docker ps -aq --filter "name=pytest"', hide='stdout')
containers = result.stdout.strip().replace('\n', ' ')
if containers:
ctx.run(f'docker rm -f {containers}')
ctx.run('docker network prune -f')
with suppress(UnexpectedExit):
# returns 1 if nothing killed
ctx.run('sudo pkill -ef -9 brewblox-amd64.sim')
@task()
def image(ctx: Context, tag='local'):
with ctx.cd(ROOT):
ctx.run(f'docker build --load -t ghcr.io/brewblox/brewblox-devcon-spark:{tag} -f Dockerfile.service .')
@task()
def buildx(ctx: Context, tag='local', platform='linux/amd64,linux/arm/v7,linux/arm64/v8'):
with ctx.cd(ROOT):
ctx.run(
f'docker buildx build --no-cache --platform {platform} -t ghcr.io/brewblox/brewblox-devcon-spark:{tag} -f Dockerfile.service .'
)
@task()
def flasher_image(ctx: Context, tag='local'):
with ctx.cd(ROOT):
ctx.run(f'docker build --load -t ghcr.io/brewblox/brewblox-firmware-flasher:{tag} -f Dockerfile.flasher .')
@task()
def flasher_buildx(ctx: Context, tag='local', platform='linux/amd64,linux/arm/v7,linux/arm64/v8'):
with ctx.cd(ROOT):
ctx.run(
f'docker buildx build --no-cache --platform {platform} -t ghcr.io/brewblox/brewblox-firmware-flasher:{tag} -f Dockerfile.flasher .'
)