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
)
This commit is contained in:
parent
f7c39f6a04
commit
c8661e0505
|
@ -91,7 +91,10 @@ class ComposeV1Builder(base.BaseBuilder):
|
||||||
if cconfig['cpuset_cpus'] != 'all':
|
if cconfig['cpuset_cpus'] != 'all':
|
||||||
cmd.append('--cpuset-cpus=%s' % cconfig['cpuset_cpus'])
|
cmd.append('--cpuset-cpus=%s' % cconfig['cpuset_cpus'])
|
||||||
else:
|
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,
|
self.string_arg(cconfig, cmd,
|
||||||
'stop_grace_period', '--stop-timeout',
|
'stop_grace_period', '--stop-timeout',
|
||||||
|
|
|
@ -100,7 +100,10 @@ class PodmanBuilder(base.BaseBuilder):
|
||||||
if cconfig['cpuset_cpus'] != 'all':
|
if cconfig['cpuset_cpus'] != 'all':
|
||||||
cmd.append('--cpuset-cpus=%s' % cconfig['cpuset_cpus'])
|
cmd.append('--cpuset-cpus=%s' % cconfig['cpuset_cpus'])
|
||||||
else:
|
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,
|
self.string_arg(cconfig, cmd,
|
||||||
'stop_grace_period', '--stop-timeout',
|
'stop_grace_period', '--stop-timeout',
|
||||||
|
|
|
@ -16,6 +16,7 @@ import collections
|
||||||
import inspect
|
import inspect
|
||||||
import json
|
import json
|
||||||
import mock
|
import mock
|
||||||
|
import sys
|
||||||
import tenacity
|
import tenacity
|
||||||
|
|
||||||
from paunch.builder import base as basebuilder
|
from paunch.builder import base as basebuilder
|
||||||
|
@ -26,10 +27,20 @@ from paunch.tests import base
|
||||||
|
|
||||||
class TestBaseBuilder(base.TestCase):
|
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",
|
@mock.patch("paunch.builder.base.BaseBuilder.delete_updated",
|
||||||
return_value=False)
|
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_call = tenacity.wait.wait_random_exponential.__call__
|
||||||
orig_argspec = inspect.getargspec(orig_call)
|
orig_argspec = inspect.getargspec(orig_call)
|
||||||
config = {
|
config = {
|
||||||
|
@ -168,7 +179,7 @@ three-12345678 three''', '', 0),
|
||||||
'--label', 'container_name=one',
|
'--label', 'container_name=one',
|
||||||
'--label', 'managed_by=tester',
|
'--label', 'managed_by=tester',
|
||||||
'--label', 'config_data=%s' % json.dumps(config['one']),
|
'--label', 'config_data=%s' % json.dumps(config['one']),
|
||||||
'--detach=true', '--cpuset-cpus=0,1,2,3',
|
'--detach=true',
|
||||||
'centos:7'], mock.ANY
|
'centos:7'], mock.ANY
|
||||||
),
|
),
|
||||||
# run two
|
# run two
|
||||||
|
@ -178,7 +189,7 @@ three-12345678 three''', '', 0),
|
||||||
'--label', 'container_name=two',
|
'--label', 'container_name=two',
|
||||||
'--label', 'managed_by=tester',
|
'--label', 'managed_by=tester',
|
||||||
'--label', 'config_data=%s' % json.dumps(config['two']),
|
'--label', 'config_data=%s' % json.dumps(config['two']),
|
||||||
'--detach=true', '--cpuset-cpus=0,1,2,3',
|
'--detach=true',
|
||||||
'centos:7'], mock.ANY
|
'centos:7'], mock.ANY
|
||||||
),
|
),
|
||||||
# run four
|
# run four
|
||||||
|
@ -188,7 +199,7 @@ three-12345678 three''', '', 0),
|
||||||
'--label', 'container_name=four',
|
'--label', 'container_name=four',
|
||||||
'--label', 'managed_by=tester',
|
'--label', 'managed_by=tester',
|
||||||
'--label', 'config_data=%s' % json.dumps(config['four']),
|
'--label', 'config_data=%s' % json.dumps(config['four']),
|
||||||
'--detach=true', '--cpuset-cpus=0,1,2,3',
|
'--detach=true',
|
||||||
'centos:7'], mock.ANY
|
'centos:7'], mock.ANY
|
||||||
),
|
),
|
||||||
# execute within four
|
# 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.container_names")
|
||||||
@mock.patch("paunch.runner.BaseRunner.discover_container_name",
|
@mock.patch("paunch.runner.BaseRunner.discover_container_name",
|
||||||
return_value='one')
|
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 = {
|
config = {
|
||||||
# running with the same config and given an ephemeral name
|
# running with the same config and given an ephemeral name
|
||||||
'one': {
|
'one': {
|
||||||
|
@ -270,7 +280,13 @@ three-12345678 three''', '', 0),
|
||||||
r.execute = exe
|
r.execute = exe
|
||||||
|
|
||||||
builder = compose1.ComposeV1Builder('foo', config, r)
|
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(0, deploy_status_code)
|
||||||
self.assertEqual([
|
self.assertEqual([
|
||||||
'Created two-12345678',
|
'Created two-12345678',
|
||||||
|
@ -470,8 +486,7 @@ three-12345678 three''', '', 0),
|
||||||
self.assertIn(arg, cmd)
|
self.assertIn(arg, cmd)
|
||||||
|
|
||||||
@mock.patch('paunch.runner.DockerRunner', autospec=True)
|
@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, runner):
|
||||||
def test_container_run_args_lists(self, mock_cpu, runner):
|
|
||||||
config = {
|
config = {
|
||||||
'one': {
|
'one': {
|
||||||
'image': 'centos:7',
|
'image': 'centos:7',
|
||||||
|
@ -503,7 +518,6 @@ three-12345678 three''', '', 0),
|
||||||
'--group-add=docker', '--group-add=zuul',
|
'--group-add=docker', '--group-add=zuul',
|
||||||
'--volume=/foo:/foo:rw', '--volume=/bar:/bar:ro',
|
'--volume=/foo:/foo:rw', '--volume=/bar:/bar:ro',
|
||||||
'--volumes-from=two', '--volumes-from=three',
|
'--volumes-from=two', '--volumes-from=three',
|
||||||
'--cpuset-cpus=0,1,2,3',
|
|
||||||
'--cap-add=SYS_ADMIN', '--cap-add=SETUID', '--cap-drop=NET_RAW',
|
'--cap-add=SYS_ADMIN', '--cap-add=SETUID', '--cap-drop=NET_RAW',
|
||||||
'centos:7', 'ls', '-l', '/foo'],
|
'centos:7', 'ls', '-l', '/foo'],
|
||||||
cmd
|
cmd
|
||||||
|
|
|
@ -20,8 +20,7 @@ from paunch.tests import test_builder_base as tbb
|
||||||
|
|
||||||
class TestComposeV1Builder(tbb.TestBaseBuilder):
|
class TestComposeV1Builder(tbb.TestBaseBuilder):
|
||||||
@mock.patch('paunch.runner.DockerRunner', autospec=True)
|
@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, runner):
|
||||||
def test_cont_run_args(self, mock_cpu, runner):
|
|
||||||
config = {
|
config = {
|
||||||
'one': {
|
'one': {
|
||||||
'image': 'centos:7',
|
'image': 'centos:7',
|
||||||
|
@ -84,8 +83,7 @@ class TestComposeV1Builder(tbb.TestBaseBuilder):
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch('paunch.runner.DockerRunner', autospec=True)
|
@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, runner):
|
||||||
def test_cont_run_args_validation_true(self, mock_cpu, runner):
|
|
||||||
config = {
|
config = {
|
||||||
'one': {
|
'one': {
|
||||||
'image': 'foo',
|
'image': 'foo',
|
||||||
|
@ -99,15 +97,12 @@ class TestComposeV1Builder(tbb.TestBaseBuilder):
|
||||||
self.assertTrue(builder.container_run_args(cmd, 'one'))
|
self.assertTrue(builder.container_run_args(cmd, 'one'))
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
['docker', '--detach=true',
|
['docker', '--detach=true',
|
||||||
'--volume=/foo:/foo:rw', '--volume=/bar:/bar:ro',
|
'--volume=/foo:/foo:rw', '--volume=/bar:/bar:ro', 'foo'],
|
||||||
'--cpuset-cpus=0,1,2,3',
|
|
||||||
'foo'],
|
|
||||||
cmd
|
cmd
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch('paunch.runner.DockerRunner', autospec=True)
|
@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, runner):
|
||||||
def test_cont_run_args_validation_false(self, mock_cpu, runner):
|
|
||||||
config = {
|
config = {
|
||||||
'one': {
|
'one': {
|
||||||
'image': 'foo',
|
'image': 'foo',
|
||||||
|
@ -121,7 +116,6 @@ class TestComposeV1Builder(tbb.TestBaseBuilder):
|
||||||
self.assertFalse(builder.container_run_args(cmd, 'one'))
|
self.assertFalse(builder.container_run_args(cmd, 'one'))
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
['docker', '--detach=true',
|
['docker', '--detach=true',
|
||||||
'--volume=/foo:/foo:rw', '--volume=/bar:/bar:ro',
|
'--volume=/foo:/foo:rw', '--volume=/bar:/bar:ro', 'foo'],
|
||||||
'--cpuset-cpus=0,1,2,3', 'foo'],
|
|
||||||
cmd
|
cmd
|
||||||
)
|
)
|
||||||
|
|
|
@ -20,8 +20,7 @@ from paunch.tests import test_builder_base as base
|
||||||
|
|
||||||
class TestPodmanBuilder(base.TestBaseBuilder):
|
class TestPodmanBuilder(base.TestBaseBuilder):
|
||||||
|
|
||||||
@mock.patch("psutil.Process.cpu_affinity", return_value=[0, 1, 2, 3])
|
def test_cont_run_args(self):
|
||||||
def test_cont_run_args(self, mock_cpu):
|
|
||||||
config = {
|
config = {
|
||||||
'one': {
|
'one': {
|
||||||
'image': 'centos:7',
|
'image': 'centos:7',
|
||||||
|
@ -67,16 +66,13 @@ class TestPodmanBuilder(base.TestBaseBuilder):
|
||||||
'--hostname=foohostname',
|
'--hostname=foohostname',
|
||||||
'--add-host=foohost:127.0.0.1',
|
'--add-host=foohost:127.0.0.1',
|
||||||
'--add-host=barhost:127.0.0.2',
|
'--add-host=barhost:127.0.0.2',
|
||||||
'--cpuset-cpus=0,1,2,3',
|
|
||||||
'--cap-add=SYS_ADMIN', '--cap-add=SETUID', '--cap-drop=NET_RAW',
|
'--cap-add=SYS_ADMIN', '--cap-add=SETUID', '--cap-drop=NET_RAW',
|
||||||
'centos:7'],
|
'centos:7'],
|
||||||
cmd
|
cmd
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch("psutil.Process.cpu_affinity",
|
|
||||||
return_value=[0, 1, 2, 3, 4, 5, 6, 7])
|
|
||||||
@mock.patch('paunch.runner.PodmanRunner', autospec=True)
|
@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 = {
|
config = {
|
||||||
'one': {
|
'one': {
|
||||||
'image': 'foo',
|
'image': 'foo',
|
||||||
|
@ -90,15 +86,12 @@ class TestPodmanBuilder(base.TestBaseBuilder):
|
||||||
self.assertTrue(builder.container_run_args(cmd, 'one'))
|
self.assertTrue(builder.container_run_args(cmd, 'one'))
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
['podman', '--conmon-pidfile=/var/run/one.pid', '--detach=true',
|
['podman', '--conmon-pidfile=/var/run/one.pid', '--detach=true',
|
||||||
'--volume=/foo:/foo:rw', '--volume=/bar:/bar:ro',
|
'--volume=/foo:/foo:rw', '--volume=/bar:/bar:ro', 'foo'],
|
||||||
'--cpuset-cpus=0,1,2,3,4,5,6,7', 'foo'],
|
|
||||||
cmd
|
cmd
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch("psutil.Process.cpu_affinity",
|
|
||||||
return_value=[0, 1, 2, 3, 4, 5, 6, 7])
|
|
||||||
@mock.patch('paunch.runner.PodmanRunner', autospec=True)
|
@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 = {
|
config = {
|
||||||
'one': {
|
'one': {
|
||||||
'image': 'foo',
|
'image': 'foo',
|
||||||
|
@ -112,7 +105,6 @@ class TestPodmanBuilder(base.TestBaseBuilder):
|
||||||
self.assertFalse(builder.container_run_args(cmd, 'one'))
|
self.assertFalse(builder.container_run_args(cmd, 'one'))
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
['podman', '--conmon-pidfile=/var/run/one.pid', '--detach=true',
|
['podman', '--conmon-pidfile=/var/run/one.pid', '--detach=true',
|
||||||
'--volume=/foo:/foo:rw', '--volume=/bar:/bar:ro',
|
'--volume=/foo:/foo:rw', '--volume=/bar:/bar:ro', 'foo'],
|
||||||
'--cpuset-cpus=0,1,2,3,4,5,6,7', 'foo'],
|
|
||||||
cmd
|
cmd
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue