Delete HA metadata proxy PID and config with elevated privileges
Both files cannot be deleted with the default permissions because
those files are created by the "root" user.
Conflicts:
neutron/agent/metadata/driver.py
neutron/tests/functional/agent/l3/framework.py
neutron/tests/unit/agent/dhcp/test_agent.py
Change-Id: I73dd37b3104fac8d3172f520f71cffd85d040c4b
Closes-Bug: #1907695
(cherry picked from commit 0a0f647ea0
)
This commit is contained in:
parent
87fce78fee
commit
28cf6786f4
@ -113,7 +113,8 @@ class ProcessManager(MonitoredProcess):
|
||||
utils.execute(cmd, run_as_root=self.run_as_root)
|
||||
# In the case of shutting down, remove the pid file
|
||||
if sig == '9':
|
||||
fileutils.delete_if_exists(self.get_pid_file_name())
|
||||
utils.delete_if_exists(self.get_pid_file_name(),
|
||||
run_as_root=self.run_as_root)
|
||||
elif pid:
|
||||
LOG.debug('%(service)s process for %(uuid)s pid %(pid)d is stale, '
|
||||
'ignoring signal %(signal)s',
|
||||
|
@ -38,6 +38,7 @@ from neutron._i18n import _
|
||||
from neutron.agent.linux import xenapi_root_helper
|
||||
from neutron.common import utils
|
||||
from neutron.conf.agent import common as config
|
||||
from neutron.privileged.agent.linux import utils as priv_utils
|
||||
from neutron import wsgi
|
||||
|
||||
|
||||
@ -394,6 +395,14 @@ def is_effective_group(group_id_or_name):
|
||||
return group_id_or_name == effective_group_name
|
||||
|
||||
|
||||
def delete_if_exists(path, run_as_root=False):
|
||||
"""Delete a path, executed as normal user or with elevated privileges"""
|
||||
if run_as_root:
|
||||
priv_utils.delete_if_exists(path)
|
||||
else:
|
||||
fileutils.delete_if_exists(path)
|
||||
|
||||
|
||||
class UnixDomainHTTPConnection(httplib.HTTPConnection):
|
||||
"""Connection class for HTTP over UNIX domain socket."""
|
||||
def __init__(self, host, port=None, strict=None, timeout=None,
|
||||
|
@ -13,7 +13,6 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import errno
|
||||
import grp
|
||||
import os
|
||||
import pwd
|
||||
@ -30,6 +29,7 @@ from neutron._i18n import _
|
||||
from neutron.agent.l3 import ha_router
|
||||
from neutron.agent.l3 import namespaces
|
||||
from neutron.agent.linux import external_process
|
||||
from neutron.agent.linux import utils as linux_utils
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -163,13 +163,7 @@ class HaproxyConfigurator(object):
|
||||
cfg_path = os.path.join(
|
||||
HaproxyConfigurator.get_config_path(state_path),
|
||||
"%s.conf" % uuid)
|
||||
try:
|
||||
os.unlink(cfg_path)
|
||||
except OSError as ex:
|
||||
# It can happen that this function is called but metadata proxy
|
||||
# was never spawned so its config file won't exist
|
||||
if ex.errno != errno.ENOENT:
|
||||
raise
|
||||
linux_utils.delete_if_exists(cfg_path, run_as_root=True)
|
||||
|
||||
|
||||
class MetadataDriver(object):
|
||||
|
@ -12,9 +12,11 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
from oslo_concurrency import processutils
|
||||
from oslo_utils import fileutils
|
||||
|
||||
from neutron import privileged
|
||||
|
||||
@ -40,3 +42,8 @@ def _find_listen_pids_namespace(namespace):
|
||||
if m:
|
||||
pids.add(m.group('pid'))
|
||||
return list(pids)
|
||||
|
||||
|
||||
@privileged.default.entrypoint
|
||||
def delete_if_exists(path, remove=os.unlink):
|
||||
fileutils.delete_if_exists(path, remove=remove)
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
import copy
|
||||
import functools
|
||||
import os
|
||||
|
||||
import mock
|
||||
import netaddr
|
||||
@ -435,12 +436,15 @@ class L3AgentTestFramework(base.BaseSudoTestCase):
|
||||
def _namespace_exists(self, namespace):
|
||||
return ip_lib.network_namespace_exists(namespace)
|
||||
|
||||
def _metadata_proxy_exists(self, conf, router):
|
||||
pm = external_process.ProcessManager(
|
||||
def _metadata_proxy(self, conf, router):
|
||||
return external_process.ProcessManager(
|
||||
conf,
|
||||
router.router_id,
|
||||
router.ns_name,
|
||||
service=metadata_driver.HAPROXY_SERVICE)
|
||||
|
||||
def _metadata_proxy_exists(self, conf, router):
|
||||
pm = self._metadata_proxy(conf, router)
|
||||
return pm.active
|
||||
|
||||
def device_exists_with_ips_and_mac(self, expected_device, name_getter,
|
||||
@ -501,9 +505,19 @@ class L3AgentTestFramework(base.BaseSudoTestCase):
|
||||
# then the devices and iptable rules have also been deleted,
|
||||
# so there's no need to check that explicitly.
|
||||
self.assertFalse(self._namespace_exists(router.ns_name))
|
||||
common_utils.wait_until_true(
|
||||
lambda: not self._metadata_proxy_exists(self.agent.conf, router),
|
||||
timeout=10)
|
||||
try:
|
||||
common_utils.wait_until_true(
|
||||
lambda: not self._metadata_proxy_exists(self.agent.conf,
|
||||
router),
|
||||
timeout=10)
|
||||
except common_utils.WaitTimeout:
|
||||
pm = self._metadata_proxy(self.agent.conf, router)
|
||||
pid_file = pm.get_pid_file_name()
|
||||
if os.path.exists(pid_file):
|
||||
msg = 'PID file %s still exists and it should not.' % pid_file
|
||||
else:
|
||||
msg = 'PID file %s is not present.' % pid_file
|
||||
self.fail(msg)
|
||||
|
||||
def _assert_snat_chains(self, router):
|
||||
self.assertFalse(router.iptables_manager.is_chain_empty(
|
||||
|
@ -34,6 +34,7 @@ from neutron.agent.dhcp import agent as dhcp_agent
|
||||
from neutron.agent import dhcp_agent as entry
|
||||
from neutron.agent.linux import dhcp
|
||||
from neutron.agent.linux import interface
|
||||
from neutron.agent.linux import utils as linux_utils
|
||||
from neutron.agent.metadata import driver as metadata_driver
|
||||
from neutron.common import config as common_config
|
||||
from neutron.common import utils
|
||||
@ -759,6 +760,12 @@ class TestDhcpAgentEventHandler(base.BaseTestCase):
|
||||
self.mock_resize_p = mock.patch('neutron.agent.dhcp.agent.'
|
||||
'DhcpAgent._resize_process_pool')
|
||||
self.mock_resize = self.mock_resize_p.start()
|
||||
self.mock_wait_until_address_ready_p = mock.patch(
|
||||
'neutron.agent.linux.ip_lib.'
|
||||
'IpAddrCommand.wait_until_address_ready')
|
||||
self.mock_wait_until_address_ready_p.start()
|
||||
mock.patch.object(linux_utils, 'delete_if_exists').start()
|
||||
self.addCleanup(self.mock_wait_until_address_ready_p.stop)
|
||||
|
||||
def _process_manager_constructor_call(self, ns=FAKE_NETWORK_DHCP_NS):
|
||||
return mock.call(conf=cfg.CONF,
|
||||
|
@ -55,6 +55,7 @@ from neutron.agent.linux import ip_lib
|
||||
from neutron.agent.linux import iptables_manager
|
||||
from neutron.agent.linux import pd
|
||||
from neutron.agent.linux import ra
|
||||
from neutron.agent.linux import utils as linux_utils
|
||||
from neutron.agent.metadata import driver as metadata_driver
|
||||
from neutron.agent import rpc as agent_rpc
|
||||
from neutron.conf.agent import common as agent_config
|
||||
@ -3060,9 +3061,10 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
|
||||
dvr_snat_ns.SNAT_NS_PREFIX + 'foo']
|
||||
other_namespaces = ['unknown']
|
||||
|
||||
self._cleanup_namespace_test(stale_namespaces,
|
||||
[],
|
||||
other_namespaces)
|
||||
with mock.patch.object(linux_utils, 'delete_if_exists'):
|
||||
self._cleanup_namespace_test(stale_namespaces,
|
||||
[],
|
||||
other_namespaces)
|
||||
|
||||
def test_cleanup_namespace_with_registered_router_ids(self):
|
||||
stale_namespaces = [namespaces.NS_PREFIX + 'cccc',
|
||||
@ -3072,9 +3074,10 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
|
||||
{'id': 'aaaa', 'distributed': False}]
|
||||
other_namespaces = ['qdhcp-aabbcc', 'unknown']
|
||||
|
||||
self._cleanup_namespace_test(stale_namespaces,
|
||||
router_list,
|
||||
other_namespaces)
|
||||
with mock.patch.object(linux_utils, 'delete_if_exists'):
|
||||
self._cleanup_namespace_test(stale_namespaces,
|
||||
router_list,
|
||||
other_namespaces)
|
||||
|
||||
def test_create_dvr_gateway(self):
|
||||
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
|
||||
|
Loading…
Reference in New Issue
Block a user