Skip to content

Commit 34bc52d

Browse files
authored
Merge branch 'beta-sync-node' into no-volume-limits
2 parents 25149bf + a690b1e commit 34bc52d

File tree

10 files changed

+109
-24
lines changed

10 files changed

+109
-24
lines changed

.github/workflows/publish.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ on:
88
- beta
99
- stable
1010
- sync-node
11+
- beta-sync-node
1112

1213
jobs:
1314
create_release:

node_cli/cli/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
__version__ = '2.2.0'
22

3+
34
if __name__ == "__main__":
45
print(__version__)

node_cli/configs/env.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@
4444
'DEFAULT_GAS_PRICE_WEI': '',
4545
'DISABLE_IMA': '',
4646
'SKIP_DOCKER_CONFIG': '',
47-
'ENFORCE_BTRFS': ''
47+
'ENFORCE_BTRFS': '',
48+
'SKIP_DOCKER_CLEANUP': ''
4849
}
4950

5051

node_cli/core/node.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ def init(env_filepath):
127127
env = get_node_env(env_filepath)
128128
if env is None:
129129
return
130+
configure_firewall_rules()
130131
inited_ok = init_op(env_filepath, env)
131132
if not inited_ok:
132133
error_exit(

node_cli/operations/base.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,13 @@
4343
from node_cli.core.checks import CheckType, run_checks as run_host_checks
4444
from node_cli.core.iptables import configure_iptables
4545
from node_cli.utils.docker_utils import (
46-
compose_rm, compose_up, remove_dynamic_containers, compose_up_sync
46+
compose_rm,
47+
compose_up,
48+
compose_up_sync,
49+
docker_cleanup,
50+
remove_dynamic_containers
4751
)
48-
from node_cli.utils.meta import update_meta
52+
from node_cli.utils.meta import get_meta_info, update_meta
4953
from node_cli.utils.print_formatters import print_failed_requirements_checks
5054

5155

@@ -110,6 +114,16 @@ def update(env_filepath: str, env: Dict) -> None:
110114
)
111115
init_shared_space_volume(env['ENV_TYPE'])
112116

117+
current_stream = get_meta_info().config_stream
118+
skip_cleanup = env.get('SKIP_DOCKER_CLEANUP') == 'True'
119+
if not skip_cleanup and current_stream != env['CONTAINER_CONFIGS_STREAM']:
120+
logger.info(
121+
'Stream version was changed from %s to %s',
122+
current_stream,
123+
env['CONTAINER_CONFIGS_STREAM']
124+
)
125+
docker_cleanup()
126+
113127
update_meta(
114128
VERSION,
115129
env['CONTAINER_CONFIGS_STREAM'],

node_cli/utils/docker_utils.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,3 +256,42 @@ def restart_nginx_container(dutils=None):
256256
dutils = dutils or docker_client()
257257
nginx_container = dutils.containers.get(NGINX_CONTAINER_NAME)
258258
nginx_container.restart()
259+
260+
261+
def remove_images(images, dclient=None):
262+
dc = dclient or docker_client()
263+
for image in images:
264+
dc.images.remove(image.id)
265+
266+
267+
def get_used_images(dclient=None):
268+
dc = dclient or docker_client()
269+
return [c.image for c in dc.containers.list()]
270+
271+
272+
def cleanup_unused_images(dclient=None, ignore=None):
273+
logger.info('Removing unused docker images')
274+
ignore = ignore or []
275+
dc = dclient or docker_client()
276+
used = get_used_images(dclient=dc)
277+
remove_images(
278+
filter(lambda i: i not in used and i not in ignore, dc.images.list()),
279+
dclient=dc
280+
)
281+
282+
283+
def system_prune():
284+
logger.info('Removing dangling docker artifacts')
285+
cmd = ['docker', 'system', 'prune', '-f']
286+
run_cmd(cmd=cmd)
287+
288+
289+
def docker_cleanup(dclient=None, ignore=None):
290+
ignore = ignore or []
291+
try:
292+
dc = dclient or docker_client()
293+
cleanup_unused_images(dclient=dc, ignore=ignore)
294+
system_prune()
295+
except Exception as e:
296+
logger.warning('Image cleanuping errored with %s', e)
297+
logger.debug('Image cleanuping errored', exc_info=True)

tests/conftest.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -148,25 +148,33 @@ def removed_containers_folder():
148148

149149

150150
@pytest.fixture()
151-
def simple_image():
152-
client = docker.from_env()
151+
def dclient():
152+
return docker.from_env()
153+
154+
155+
@pytest.fixture()
156+
def simple_image(dclient):
153157
name = 'simple-image'
154158
try:
155-
client.images.build(
159+
dclient.images.build(
156160
tag=name,
157161
rm=True,
158162
nocache=True,
159163
path='tests/simple_container'
160164
)
161165
yield name
162166
finally:
163-
client.images.remove(name, force=True)
167+
try:
168+
dclient.images.get(name)
169+
except docker.errors.ImageNotFound:
170+
return
171+
dclient.images.remove(name, force=True)
164172

165173

166174
@pytest.fixture()
167-
def docker_hc():
168-
client = docker.from_env()
169-
return client.api.create_host_config(
175+
def docker_hc(dclient):
176+
dclient = docker.from_env()
177+
return dclient.api.create_host_config(
170178
log_config=docker.types.LogConfig(
171179
type=docker.types.LogConfig.types.JSON
172180
)

tests/core/host/docker_config_test.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from contextlib import contextmanager
66
from timeit import default_timer as timer
77

8-
import docker
98
import pytest
109

1110
from node_cli.core.docker_config import (
@@ -127,11 +126,12 @@ def test_ensure_run_dir(tmp_dir):
127126

128127

129128
@pytest.fixture
130-
def container():
131-
client = docker.from_env()
132-
c = client.containers.run('hello-world', detach=True)
133-
yield c
134-
c.remove(force=True)
129+
def container(dclient):
130+
c = dclient.containers.run('hello-world', detach=True)
131+
try:
132+
yield c
133+
finally:
134+
c.remove(force=True)
135135

136136

137137
def test_assert_no_contaners():

tests/core_node_test.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ def test_init_node(no_resource_file): # todo: write new init node test
158158
return_value=BIG_DISK_SIZE), \
159159
mock.patch('node_cli.core.host.prepare_host'), \
160160
mock.patch('node_cli.core.host.init_data_dir'), \
161+
mock.patch('node_cli.core.node.configure_firewall_rules'), \
161162
mock.patch('node_cli.core.node.init_op'), \
162163
mock.patch('node_cli.core.node.is_base_containers_alive',
163164
return_value=True), \

tests/docker_utils_test.py

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,29 @@
22
import time
33
from time import sleep
44

5-
import docker
5+
import mock
66
import pytest
77

8-
from node_cli.utils.docker_utils import save_container_logs, safe_rm
8+
from node_cli.utils.docker_utils import (
9+
docker_cleanup,
10+
save_container_logs,
11+
safe_rm
12+
)
913
from node_cli.configs import REMOVED_CONTAINERS_FOLDER_PATH
1014

1115

12-
client = docker.from_env()
13-
14-
1516
@pytest.fixture
16-
def simple_container(simple_image, docker_hc):
17+
def simple_container(dclient, simple_image, docker_hc):
1718
name = 'simple-container'
1819
c = None
1920
try:
20-
info = client.api.create_container(
21+
info = dclient.api.create_container(
2122
simple_image,
2223
detach=True,
2324
name=name,
2425
host_config=docker_hc
2526
)
26-
c = client.containers.get(info['Id'])
27+
c = dclient.containers.get(info['Id'])
2728
c.restart()
2829
yield c
2930
finally:
@@ -83,3 +84,21 @@ def test_safe_rm(simple_container, removed_containers_folder):
8384
with open(log_path) as log_file:
8485
log_lines = log_file.readlines()
8586
assert log_lines[-1] == 'signal_handler completed, exiting...\n'
87+
88+
89+
def test_docker_cleanup(dclient, simple_container):
90+
c = simple_container
91+
image = c.image
92+
docker_cleanup(dclient=dclient)
93+
assert image in dclient.images.list()
94+
95+
c.stop()
96+
docker_cleanup(dclient=dclient)
97+
assert image in dclient.images.list()
98+
99+
c.remove()
100+
docker_cleanup(dclient=dclient)
101+
assert image not in dclient.images.list()
102+
103+
with mock.patch('node_cli.utils.docker_utils.run_cmd', side_effect=ValueError):
104+
docker_cleanup(dclient=dclient)

0 commit comments

Comments
 (0)