Browse Source

podman: get cpus allowed list only when isolcpus in cmdline

When building the podman command, only get cpus allowed list when there
is isolcpus in the /proc/cmdline otherwise skip the argument.

Note: re-working the Mocks for cpu affinity so we can properly test the
/proc/cmdline reads.

Change-Id: I270c90d3adc8824991896443c6074f8f7357c942
Related-Bug: #1884765
Co-Authored-By: Alex Schultz <aschultz@redhat.com>
(cherry picked from commit 7ea9455221)
changes/49/737549/4
Emilien Macchi 2 weeks ago
committed by Alex Schultz
parent
commit
c8661e0505
5 changed files with 43 additions and 37 deletions
  1. +4
    -1
      paunch/builder/compose1.py
  2. +4
    -1
      paunch/builder/podman.py
  3. +25
    -11
      paunch/tests/test_builder_base.py
  4. +5
    -11
      paunch/tests/test_builder_compose1.py
  5. +5
    -13
      paunch/tests/test_builder_podman.py

+ 4
- 1
paunch/builder/compose1.py View File

@@ -91,7 +91,10 @@ class ComposeV1Builder(base.BaseBuilder):
if cconfig['cpuset_cpus'] != 'all':
cmd.append('--cpuset-cpus=%s' % cconfig['cpuset_cpus'])
else:
cmd.append('--cpuset-cpus=%s' % common.get_cpus_allowed_list())
with open('/proc/cmdline') as cmdline:
if 'isolcpus' in cmdline.read():
cmd.append('--cpuset-cpus=%s' %
common.get_cpus_allowed_list())

self.string_arg(cconfig, cmd,
'stop_grace_period', '--stop-timeout',


+ 4
- 1
paunch/builder/podman.py View File

@@ -100,7 +100,10 @@ class PodmanBuilder(base.BaseBuilder):
if cconfig['cpuset_cpus'] != 'all':
cmd.append('--cpuset-cpus=%s' % cconfig['cpuset_cpus'])
else:
cmd.append('--cpuset-cpus=%s' % common.get_cpus_allowed_list())
with open('/proc/cmdline') as cmdline:
if 'isolcpus' in cmdline.read():
cmd.append('--cpuset-cpus=%s' %
common.get_cpus_allowed_list())

self.string_arg(cconfig, cmd,
'stop_grace_period', '--stop-timeout',


+ 25
- 11
paunch/tests/test_builder_base.py View File

@@ -16,6 +16,7 @@ import collections
import inspect
import json
import mock
import sys
import tenacity

from paunch.builder import base as basebuilder
@@ -26,10 +27,20 @@ from paunch.tests import base

class TestBaseBuilder(base.TestCase):

@mock.patch("psutil.Process.cpu_affinity", return_value=[0, 1, 2, 3])
def setUp(self):
super(TestBaseBuilder, self).setUp()
mock_cpu_obj = mock.MagicMock()
mock_cpu_aff = mock.MagicMock()
mock_cpu_aff.return_value = [0, 1, 2, 3]
mock_cpu_obj.cpu_affinity = mock_cpu_aff
self.psutil_mock = mock.patch('psutil.Process',
return_value=mock_cpu_obj)
self.psutil_mock.start()
self.addCleanup(self.psutil_mock.stop)

@mock.patch("paunch.builder.base.BaseBuilder.delete_updated",
return_value=False)
def test_apply(self, mock_delete_updated, mock_cpu):
def test_apply(self, mock_delete_updated):
orig_call = tenacity.wait.wait_random_exponential.__call__
orig_argspec = inspect.getargspec(orig_call)
config = {
@@ -168,7 +179,7 @@ three-12345678 three''', '', 0),
'--label', 'container_name=one',
'--label', 'managed_by=tester',
'--label', 'config_data=%s' % json.dumps(config['one']),
'--detach=true', '--cpuset-cpus=0,1,2,3',
'--detach=true',
'centos:7'], mock.ANY
),
# run two
@@ -178,7 +189,7 @@ three-12345678 three''', '', 0),
'--label', 'container_name=two',
'--label', 'managed_by=tester',
'--label', 'config_data=%s' % json.dumps(config['two']),
'--detach=true', '--cpuset-cpus=0,1,2,3',
'--detach=true',
'centos:7'], mock.ANY
),
# run four
@@ -188,7 +199,7 @@ three-12345678 three''', '', 0),
'--label', 'container_name=four',
'--label', 'managed_by=tester',
'--label', 'config_data=%s' % json.dumps(config['four']),
'--detach=true', '--cpuset-cpus=0,1,2,3',
'--detach=true',
'centos:7'], mock.ANY
),
# execute within four
@@ -198,11 +209,10 @@ three-12345678 three''', '', 0),
),
])

@mock.patch("psutil.Process.cpu_affinity", return_value=[0, 1, 2, 3])
@mock.patch("paunch.runner.BaseRunner.container_names")
@mock.patch("paunch.runner.BaseRunner.discover_container_name",
return_value='one')
def test_apply_idempotency(self, mock_dname, mock_cnames, mock_cpu):
def test_apply_idempotency_with_isolcpus(self, mock_dname, mock_cnames):
config = {
# running with the same config and given an ephemeral name
'one': {
@@ -270,7 +280,13 @@ three-12345678 three''', '', 0),
r.execute = exe

builder = compose1.ComposeV1Builder('foo', config, r)
stdout, stderr, deploy_status_code = builder.apply()
if (sys.version_info > (3, 0)):
open_builtins = "builtins.open"
else:
open_builtins = "__builtin__.open"
with mock.patch(open_builtins,
mock.mock_open(read_data="isolcpus")):
stdout, stderr, deploy_status_code = builder.apply()
self.assertEqual(0, deploy_status_code)
self.assertEqual([
'Created two-12345678',
@@ -470,8 +486,7 @@ three-12345678 three''', '', 0),
self.assertIn(arg, cmd)

@mock.patch('paunch.runner.DockerRunner', autospec=True)
@mock.patch("psutil.Process.cpu_affinity", return_value=[0, 1, 2, 3])
def test_container_run_args_lists(self, mock_cpu, runner):
def test_container_run_args_lists(self, runner):
config = {
'one': {
'image': 'centos:7',
@@ -503,7 +518,6 @@ three-12345678 three''', '', 0),
'--group-add=docker', '--group-add=zuul',
'--volume=/foo:/foo:rw', '--volume=/bar:/bar:ro',
'--volumes-from=two', '--volumes-from=three',
'--cpuset-cpus=0,1,2,3',
'--cap-add=SYS_ADMIN', '--cap-add=SETUID', '--cap-drop=NET_RAW',
'centos:7', 'ls', '-l', '/foo'],
cmd


+ 5
- 11
paunch/tests/test_builder_compose1.py View File

@@ -20,8 +20,7 @@ from paunch.tests import test_builder_base as tbb

class TestComposeV1Builder(tbb.TestBaseBuilder):
@mock.patch('paunch.runner.DockerRunner', autospec=True)
@mock.patch("psutil.Process.cpu_affinity", return_value=[0, 1, 2, 3])
def test_cont_run_args(self, mock_cpu, runner):
def test_cont_run_args(self, runner):
config = {
'one': {
'image': 'centos:7',
@@ -84,8 +83,7 @@ class TestComposeV1Builder(tbb.TestBaseBuilder):
)

@mock.patch('paunch.runner.DockerRunner', autospec=True)
@mock.patch("psutil.Process.cpu_affinity", return_value=[0, 1, 2, 3])
def test_cont_run_args_validation_true(self, mock_cpu, runner):
def test_cont_run_args_validation_true(self, runner):
config = {
'one': {
'image': 'foo',
@@ -99,15 +97,12 @@ class TestComposeV1Builder(tbb.TestBaseBuilder):
self.assertTrue(builder.container_run_args(cmd, 'one'))
self.assertEqual(
['docker', '--detach=true',
'--volume=/foo:/foo:rw', '--volume=/bar:/bar:ro',
'--cpuset-cpus=0,1,2,3',
'foo'],
'--volume=/foo:/foo:rw', '--volume=/bar:/bar:ro', 'foo'],
cmd
)

@mock.patch('paunch.runner.DockerRunner', autospec=True)
@mock.patch("psutil.Process.cpu_affinity", return_value=[0, 1, 2, 3])
def test_cont_run_args_validation_false(self, mock_cpu, runner):
def test_cont_run_args_validation_false(self, runner):
config = {
'one': {
'image': 'foo',
@@ -121,7 +116,6 @@ class TestComposeV1Builder(tbb.TestBaseBuilder):
self.assertFalse(builder.container_run_args(cmd, 'one'))
self.assertEqual(
['docker', '--detach=true',
'--volume=/foo:/foo:rw', '--volume=/bar:/bar:ro',
'--cpuset-cpus=0,1,2,3', 'foo'],
'--volume=/foo:/foo:rw', '--volume=/bar:/bar:ro', 'foo'],
cmd
)

+ 5
- 13
paunch/tests/test_builder_podman.py View File

@@ -20,8 +20,7 @@ from paunch.tests import test_builder_base as base

class TestPodmanBuilder(base.TestBaseBuilder):

@mock.patch("psutil.Process.cpu_affinity", return_value=[0, 1, 2, 3])
def test_cont_run_args(self, mock_cpu):
def test_cont_run_args(self):
config = {
'one': {
'image': 'centos:7',
@@ -67,16 +66,13 @@ class TestPodmanBuilder(base.TestBaseBuilder):
'--hostname=foohostname',
'--add-host=foohost:127.0.0.1',
'--add-host=barhost:127.0.0.2',
'--cpuset-cpus=0,1,2,3',
'--cap-add=SYS_ADMIN', '--cap-add=SETUID', '--cap-drop=NET_RAW',
'centos:7'],
cmd
)

@mock.patch("psutil.Process.cpu_affinity",
return_value=[0, 1, 2, 3, 4, 5, 6, 7])
@mock.patch('paunch.runner.PodmanRunner', autospec=True)
def test_cont_run_args_validation_true(self, runner, mock_cpu):
def test_cont_run_args_validation_true(self, runner):
config = {
'one': {
'image': 'foo',
@@ -90,15 +86,12 @@ class TestPodmanBuilder(base.TestBaseBuilder):
self.assertTrue(builder.container_run_args(cmd, 'one'))
self.assertEqual(
['podman', '--conmon-pidfile=/var/run/one.pid', '--detach=true',
'--volume=/foo:/foo:rw', '--volume=/bar:/bar:ro',
'--cpuset-cpus=0,1,2,3,4,5,6,7', 'foo'],
'--volume=/foo:/foo:rw', '--volume=/bar:/bar:ro', 'foo'],
cmd
)

@mock.patch("psutil.Process.cpu_affinity",
return_value=[0, 1, 2, 3, 4, 5, 6, 7])
@mock.patch('paunch.runner.PodmanRunner', autospec=True)
def test_cont_run_args_validation_false(self, runner, mock_cpu):
def test_cont_run_args_validation_false(self, runner):
config = {
'one': {
'image': 'foo',
@@ -112,7 +105,6 @@ class TestPodmanBuilder(base.TestBaseBuilder):
self.assertFalse(builder.container_run_args(cmd, 'one'))
self.assertEqual(
['podman', '--conmon-pidfile=/var/run/one.pid', '--detach=true',
'--volume=/foo:/foo:rw', '--volume=/bar:/bar:ro',
'--cpuset-cpus=0,1,2,3,4,5,6,7', 'foo'],
'--volume=/foo:/foo:rw', '--volume=/bar:/bar:ro', 'foo'],
cmd
)

Loading…
Cancel
Save