Merge "Support update parameters of a resource"

This commit is contained in:
Zuul 2018-07-17 15:00:08 +00:00 committed by Gerrit Code Review
commit b9c82a8724
4 changed files with 100 additions and 10 deletions

View File

@ -14,13 +14,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import shutil
import os
import sys
import glob
import os
import shutil
import socket
import sys
import pcmk
import socket
from charmhelpers.core.hookenv import (
is_leader,
@ -340,6 +340,15 @@ def ha_relation_changed():
'-inf: pingd lte 0' % (res_name, res_name))
pcmk.commit(cmd)
else:
# the resource already exists so it will be updated.
code = pcmk.crm_update_resource(res_name, res_type,
resource_params.get(res_name))
if code != 0:
msg = "Cannot update pcmkr resource: {}".format(res_name)
status_set('blocked', msg)
raise Exception(msg)
log('Configuring Groups: %s' % (groups), level=DEBUG)
for grp_name, grp_params in groups.iteritems():
if not pcmk.crm_opt_exists(grp_name):

View File

@ -16,6 +16,7 @@ import commands
import re
import subprocess
import socket
import tempfile
import time
import xml.etree.ElementTree as etree
@ -24,6 +25,9 @@ from StringIO import StringIO
from charmhelpers.core.hookenv import (
log,
ERROR,
INFO,
DEBUG,
WARNING,
)
@ -51,7 +55,7 @@ def wait_for_pcmk(retries=12, sleep=10):
def commit(cmd):
subprocess.call(cmd.split())
return subprocess.call(cmd.split())
def is_resource_present(resource):
@ -221,3 +225,34 @@ def crm_version():
raise ValueError('error parsin crm version: %s' % ver)
else:
return StrictVersion(matched.group(1))
def crm_update_resource(res_name, res_type, res_params=None):
"""Update a resource using `crm configure load update`
:param res_name: resource name
:param res_type: resource type (e.g. IPaddr2)
:param res_params: resource's parameters (e.g. "params ip=10.5.250.250")
"""
with tempfile.NamedTemporaryFile() as f:
f.write('primitive {} {}'.format(res_name, res_type))
if res_params:
f.write(' \\\n\t{}'.format(res_params))
else:
f.write('\n')
f.flush()
f.seek(0)
log('Updating resource {}'.format(res_name), level=INFO)
log('File content:\n{}'.format(f.read()), level=DEBUG)
cmd = "crm configure load update {}".format(f.name)
log('Update command: {}'.format(cmd))
retcode = commit(cmd)
if retcode == 0:
level = DEBUG
else:
level = WARNING
log('crm command exit code: {}'.format(retcode), level=level)
return retcode

View File

@ -14,6 +14,7 @@
import mock
import os
import shutil
import sys
import tempfile
import unittest
@ -31,6 +32,11 @@ class TestCorosyncConf(unittest.TestCase):
def setUp(self):
self.tmpdir = tempfile.mkdtemp()
self.tmpfile = tempfile.NamedTemporaryFile(delete=False)
def tearDown(self):
shutil.rmtree(self.tmpdir)
os.remove(self.tmpfile.name)
@mock.patch.object(hooks, 'write_maas_dns_address')
@mock.patch('pcmk.wait_for_pcmk')
@ -56,7 +62,13 @@ class TestCorosyncConf(unittest.TestCase):
configure_cluster_global, configure_corosync,
oldest_peer, crm_opt_exists, peer_units,
wait_for_pcmk, write_maas_dns_address):
crm_opt_exists.return_value = False
def fake_crm_opt_exists(res_name):
# res_ubuntu will take the "update resource" route
return res_name == "res_ubuntu"
crm_opt_exists.side_effect = fake_crm_opt_exists
commit.return_value = 0
oldest_peer.return_value = True
related_units.return_value = ['ha/0', 'ha/1', 'ha/2']
get_cluster_nodes.return_value = ['10.0.3.2', '10.0.3.3', '10.0.3.4']
@ -75,8 +87,10 @@ class TestCorosyncConf(unittest.TestCase):
'groups': {'grp_foo': 'res_foo'},
'colocations': {'co_foo': 'inf: grp_foo cl_foo'},
'resources': {'res_foo': 'ocf:heartbeat:IPaddr2',
'res_bar': 'ocf:heartbear:IPv6addr'},
'resource_params': {'res_foo': 'params bar'},
'res_bar': 'ocf:heartbear:IPv6addr',
'res_ubuntu': 'IPaddr2'},
'resource_params': {'res_foo': 'params bar',
'res_ubuntu': 'params ubuntu=42'},
'ms': {'ms_foo': 'res_foo meta notify=true'},
'orders': {'foo_after': 'inf: res_foo ms_foo'}}
@ -85,7 +99,10 @@ class TestCorosyncConf(unittest.TestCase):
parse_data.side_effect = fake_parse_data
hooks.ha_relation_changed()
with mock.patch.object(tempfile, "NamedTemporaryFile",
side_effect=lambda: self.tmpfile):
hooks.ha_relation_changed()
relation_set.assert_any_call(relation_id='hanode:1', ready=True)
configure_stonith.assert_called_with()
configure_monitor_host.assert_called_with()
@ -101,7 +118,11 @@ class TestCorosyncConf(unittest.TestCase):
('ms', 'ms'),
('order', 'orders')]:
for name, params in rel_get_data[key].items():
if name in rel_get_data['resource_params']:
if name == "res_ubuntu":
commit.assert_any_call(
'crm configure load update %s' % self.tmpfile.name)
elif name in rel_get_data['resource_params']:
res_params = rel_get_data['resource_params'][name]
commit.assert_any_call(
'crm -w -F configure %s %s %s %s' % (kw, name, params,

View File

@ -14,6 +14,8 @@
import mock
import pcmk
import os
import tempfile
import unittest
from distutils.version import StrictVersion
@ -73,6 +75,12 @@ CRM_CONFIGURE_SHOW_XML_MAINT_MODE_TRUE = '''<?xml version="1.0" ?>
class TestPcmk(unittest.TestCase):
def setUp(self):
self.tmpfile = tempfile.NamedTemporaryFile(delete=False)
def tearDown(self):
os.remove(self.tmpfile.name)
@mock.patch('commands.getstatusoutput')
def test_crm_res_running_true(self, getstatusoutput):
getstatusoutput.return_value = (0, ("resource res_nova_consoleauth is "
@ -167,3 +175,20 @@ class TestPcmk(unittest.TestCase):
mock_check_output.assert_called_with(['crm', 'configure', 'property',
'maintenance-mode=false'],
universal_newlines=True)
@mock.patch('subprocess.call')
def test_crm_update_resource(self, mock_call):
mock_call.return_value = 0
with mock.patch.object(tempfile, "NamedTemporaryFile",
side_effect=lambda: self.tmpfile):
pcmk.crm_update_resource('res_test', 'IPaddr2',
('params ip=1.2.3.4 '
'cidr_netmask=255.255.0.0'))
mock_call.assert_any_call(['crm', 'configure', 'load',
'update', self.tmpfile.name])
with open(self.tmpfile.name, 'r') as f:
self.assertEqual(f.read(),
('primitive res_test IPaddr2 \\\n'
'\tparams ip=1.2.3.4 cidr_netmask=255.255.0.0'))