Skip to content

Commit a5664bc

Browse files
authored
Merge pull request #177 from bluesliverx/main
Add ability to label all started containers
2 parents 05d4e99 + 89cbafc commit a5664bc

File tree

7 files changed

+118
-4
lines changed

7 files changed

+118
-4
lines changed

buildrunner/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ def __init__(
8585
local_images: bool,
8686
platform: Optional[str],
8787
global_config_overrides: dict,
88+
container_labels: Optional[str] = None,
8889
): # pylint: disable=too-many-statements,too-many-branches,too-many-locals,too-many-arguments
8990
self.build_dir = build_dir
9091
self.build_results_dir = build_results_dir
@@ -141,6 +142,7 @@ def __init__(
141142
build_time=self.build_time,
142143
tmp_files=self.tmp_files,
143144
global_config_overrides=global_config_overrides,
145+
container_labels=container_labels,
144146
)
145147
self.buildrunner_config = BuildRunnerConfig.get_instance()
146148

buildrunner/cli.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ def parse_args(argv):
6868
help="enables debug logging",
6969
)
7070

71+
parser.add_argument(
72+
"--container-labels",
73+
default=None,
74+
help=(
75+
"arbitrary labels to add to every container started by buildrunner, "
76+
"in the form of 'key1=value1,key2=value2'"
77+
),
78+
)
79+
7180
parser.add_argument(
7281
"-n",
7382
"--build-number",
@@ -396,6 +405,7 @@ def initialize_br(args: argparse.Namespace) -> BuildRunner:
396405
local_images=args.local_images,
397406
platform=args.platform,
398407
global_config_overrides=_get_global_config_overrides(args),
408+
container_labels=args.container_labels,
399409
)
400410

401411

buildrunner/config/__init__.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ def __init__(
7171
log_generated_files: bool,
7272
build_time: int,
7373
global_config_overrides: dict,
74+
# Arbitrary labels to add to all started containers, of the form key1=value1,key2=value2
75+
container_labels: Optional[str] = None,
7476
# May be passed in to add temporary files to this list as they are created
7577
tmp_files: Optional[List[str]] = None,
7678
# Used only from CLI commands that do not need a run config
@@ -83,6 +85,7 @@ def __init__(
8385
self.build_time = build_time
8486
if not self.build_time:
8587
self.build_time = epoch_time()
88+
self.container_labels = self._parse_container_labels(container_labels)
8689
self.tmp_files = tmp_files
8790

8891
self.global_config = self._load_global_config(
@@ -99,6 +102,20 @@ def __init__(
99102
self._load_run_config(run_config_file) if load_run_config else None
100103
)
101104

105+
@staticmethod
106+
def _parse_container_labels(container_labels_str: Optional[str]) -> dict:
107+
container_labels = {}
108+
if not container_labels_str:
109+
return container_labels
110+
for pair in container_labels_str.split(","):
111+
if "=" not in pair:
112+
raise BuildRunnerConfigurationError(
113+
"Invalid container label format, must be key=value"
114+
)
115+
key, value = pair.split("=", 1)
116+
container_labels[key] = value
117+
return container_labels
118+
102119
def _load_global_config(
103120
self, global_config_file: Optional[str], global_config_overrides: dict
104121
) -> GlobalConfig:

buildrunner/docker/runner.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import six
2828
import timeout_decorator
2929

30+
from buildrunner import BuildRunnerConfig
3031
from buildrunner.docker import (
3132
new_client,
3233
force_remove_container,
@@ -79,10 +80,10 @@ def __init__(self, image_name, pull_image=True, platform=None):
7980
def __init__(self, image_config, dockerd_url=None, log=None):
8081
image_name = image_config.image_name
8182
pull_image = image_config.pull_image
82-
platform = image_config.platform
83+
image_platform = image_config.platform
8384

8485
self.image_name = image_name.lower()
85-
self.platform = platform
86+
self.platform = image_platform
8687
if log and self.image_name != image_name:
8788
log.write(
8889
f"Forcing image_name to lowercase: {image_name} => {self.image_name}\n"
@@ -230,6 +231,7 @@ def start(
230231
"user": user,
231232
"working_dir": working_dir,
232233
"hostname": hostname,
234+
"labels": BuildRunnerConfig.get_instance().container_labels,
233235
"host_config": self.docker_client.create_host_config(
234236
binds=_binds,
235237
links=links,

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from setuptools import setup, find_packages
1414

1515

16-
BASE_VERSION = "3.14"
16+
BASE_VERSION = "3.15"
1717

1818
SOURCE_DIR = os.path.dirname(os.path.abspath(__file__))
1919
BUILDRUNNER_DIR = os.path.join(SOURCE_DIR, "buildrunner")

tests/test_caching.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from time import sleep
88
from unittest import mock
99

10-
from buildrunner import BuildRunner
10+
from buildrunner import BuildRunner, BuildRunnerConfig
1111
from buildrunner.docker.runner import DockerRunner
1212
from buildrunner.loggers import ConsoleLogger
1313
import pytest
@@ -28,6 +28,25 @@ def _tar_safe_extractall(tar, path=".", members=None, *, numeric_owner=False):
2828
tar.extractall(path, members, numeric_owner=numeric_owner)
2929

3030

31+
@pytest.fixture(name="initialize_config", autouse=True)
32+
def fixture_initialize_config(tmp_path):
33+
buildrunner_path = tmp_path / "buildrunner.yaml"
34+
buildrunner_path.write_text("steps: {'step1': {}}")
35+
BuildRunnerConfig.initialize_instance(
36+
build_id="123",
37+
vcs=None,
38+
build_dir=str(tmp_path),
39+
global_config_file=None,
40+
run_config_file=str(buildrunner_path),
41+
build_time=0,
42+
build_number=1,
43+
push=False,
44+
steps_to_run=None,
45+
log_generated_files=False,
46+
global_config_overrides={},
47+
)
48+
49+
3150
@pytest.fixture(name="runner")
3251
def fixture_setup_runner():
3352
image_config = DockerRunner.ImageConfig(
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import os
2+
from unittest import mock
3+
4+
import pytest
5+
6+
from buildrunner import BuildRunner, BuildRunnerConfig
7+
8+
9+
TEST_DIR = os.path.dirname(os.path.abspath(__file__))
10+
BLANK_GLOBAL_CONFIG = os.path.join(TEST_DIR, "files/blank_global_config.yaml")
11+
12+
13+
@pytest.mark.parametrize(
14+
"container_labels, result_labels",
15+
[
16+
(None, {}),
17+
("", {}),
18+
("key1=val1", {"key1": "val1"}),
19+
("key1=val1,key2=val2", {"key1": "val1", "key2": "val2"}),
20+
("key1=val1=val3,key2=val2", {"key1": "val1=val3", "key2": "val2"}),
21+
],
22+
)
23+
@mock.patch("buildrunner.detect_vcs")
24+
def test_container_labels(
25+
detect_vcs_mock,
26+
container_labels,
27+
result_labels,
28+
tmp_path,
29+
):
30+
id_string = "main-921.ie02ed8.m1705616822"
31+
type(detect_vcs_mock.return_value).id_string = mock.PropertyMock(
32+
return_value=id_string
33+
)
34+
buildrunner_path = tmp_path / "buildrunner.yaml"
35+
buildrunner_path.write_text(
36+
"""
37+
steps:
38+
build-container:
39+
build:
40+
dockerfile: |
41+
FROM {{ DOCKER_REGISTRY }}/nginx:latest
42+
RUN printf '{{ BUILDRUNNER_BUILD_NUMBER }}' > /usr/share/nginx/html/index.html
43+
"""
44+
)
45+
BuildRunner(
46+
build_dir=str(tmp_path),
47+
build_results_dir=str(tmp_path / "buildrunner.results"),
48+
global_config_file=None,
49+
run_config_file=str(buildrunner_path),
50+
build_time=0,
51+
build_number=1,
52+
push=False,
53+
cleanup_images=False,
54+
cleanup_cache=False,
55+
steps_to_run=None,
56+
publish_ports=False,
57+
log_generated_files=False,
58+
docker_timeout=30,
59+
local_images=False,
60+
platform=None,
61+
global_config_overrides={},
62+
container_labels=container_labels,
63+
)
64+
assert BuildRunnerConfig.get_instance().container_labels == result_labels

0 commit comments

Comments
 (0)