Merge pull request #1159 from me-coder/container_scaling_update

Updates handling of scale/replicas parameter in CLI and compose file
This commit is contained in:
Povilas Kanapickas 2025-04-08 02:54:32 +03:00 committed by GitHub
commit 2e46ff0db2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 155 additions and 4 deletions

1
newsfragments/267.bugfix Normal file
View File

@ -0,0 +1 @@
- Fixed the --scale flag as described in issue #267 [Podman not supporting --scale flag]

View File

@ -2107,6 +2107,22 @@ class PodmanCompose:
container_names_by_service = {} container_names_by_service = {}
self.services = services self.services = services
for service_name, service_desc in services.items(): for service_name, service_desc in services.items():
replicas = 1
if "scale" in args and args.scale is not None:
# Check `--scale` args from CLI command
scale_args = args.scale.split('=')
if service_name == scale_args[0]:
replicas = try_int(scale_args[1], fallback=1)
elif "scale" in service_desc:
# Check `scale` value from compose yaml file
replicas = try_int(service_desc.get("scale"), fallback=1)
elif (
"deploy" in service_desc
and "replicas" in service_desc.get("deploy", {})
and "replicated" == service_desc.get("deploy", {}).get("mode", '')
):
# Check `deploy: replicas:` value from compose yaml file
# Note: All conditions are necessary to handle case
replicas = try_int(service_desc.get("deploy", {}).get("replicas"), fallback=1) replicas = try_int(service_desc.get("deploy", {}).get("replicas"), fallback=1)
container_names_by_service[service_name] = [] container_names_by_service[service_name] = []
@ -3423,12 +3439,13 @@ def compose_up_parse(parser):
action="store_true", action="store_true",
help="Remove containers for services not defined in the Compose file.", help="Remove containers for services not defined in the Compose file.",
) )
# `--scale` argument needs to store as single value and not append,
# as multiple scale values could be confusing.
parser.add_argument( parser.add_argument(
"--scale", "--scale",
metavar="SERVICE=NUM", metavar="SERVICE=NUM",
action="append", help="Scale SERVICE to NUM instances. "
help="Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if " "Overrides the `scale` setting in the Compose file if present.",
"present.",
) )
parser.add_argument( parser.add_argument(
"--exit-code-from", "--exit-code-from",

View File

@ -0,0 +1,6 @@
name: podman-compose
services:
service1:
image: docker.io/library/busybox:latest
tty: true

View File

@ -0,0 +1,9 @@
name: podman-compose
services:
service1:
image: docker.io/library/busybox:latest
tty: true
deploy:
mode: replicated
replicas: 2

View File

@ -0,0 +1,7 @@
name: podman-compose
services:
service1:
image: docker.io/library/busybox:latest
tty: true
scale: 2

View File

@ -0,0 +1,111 @@
# SPDX-License-Identifier: GPL-2.0
import os
import unittest
from tests.integration.test_utils import RunSubprocessMixin
from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path
def compose_yaml_path(test_ref_folder):
return os.path.join(test_path(), "service_scale", test_ref_folder, "docker-compose.yml")
class TestComposeScale(unittest.TestCase, RunSubprocessMixin):
# scale-up using `scale` prarmeter in docker-compose.yml
def test_scaleup_scale_parameter(self):
try:
output, _, return_code = self.run_subprocess([
podman_compose_path(),
"-f",
compose_yaml_path("scaleup_scale_parameter"),
"up",
"-d",
])
self.assertEqual(return_code, 0)
output, _, return_code = self.run_subprocess([
podman_compose_path(),
"-f",
compose_yaml_path("scaleup_scale_parameter"),
"ps",
"-q",
])
self.assertEqual(len(output.splitlines()), 2)
finally:
self.run_subprocess_assert_returncode([
podman_compose_path(),
"-f",
compose_yaml_path("scaleup_scale_parameter"),
"down",
"-t",
"0",
])
# scale-up using `deploy => replicas` prarmeter in docker-compose.yml
def test_scaleup_deploy_replicas_parameter(self):
try:
output, _, return_code = self.run_subprocess([
podman_compose_path(),
"-f",
compose_yaml_path('scaleup_deploy_replicas_parameter'),
"up",
"-d",
])
self.assertEqual(return_code, 0)
output, _, return_code = self.run_subprocess([
podman_compose_path(),
"-f",
compose_yaml_path("scaleup_scale_parameter"),
"ps",
"-q",
])
self.assertEqual(len(output.splitlines()), 2)
finally:
self.run_subprocess_assert_returncode([
podman_compose_path(),
"-f",
compose_yaml_path('scaleup_deploy_replicas_parameter'),
"down",
"-t",
"0",
])
# scale-up using `--scale <SERVICE>=<number of replicas>` argument in CLI
def test_scaleup_cli(self):
try:
output, _, return_code = self.run_subprocess([
podman_compose_path(),
"-f",
compose_yaml_path('scaleup_cli'),
"up",
"-d",
])
self.assertEqual(return_code, 0)
output, _, return_code = self.run_subprocess([
podman_compose_path(),
"-f",
compose_yaml_path('scaleup_cli'),
"up",
"-d",
"--scale",
"service1=2",
])
self.assertEqual(return_code, 0)
output, _, return_code = self.run_subprocess([
podman_compose_path(),
"-f",
compose_yaml_path("scaleup_scale_parameter"),
"ps",
"-q",
])
self.assertEqual(len(output.splitlines()), 2)
finally:
self.run_subprocess_assert_returncode([
podman_compose_path(),
"-f",
compose_yaml_path('scaleup_cli'),
"down",
"-t",
"0",
])