summaryrefslogtreecommitdiff
path: root/ironic/common
diff options
context:
space:
mode:
Diffstat (limited to 'ironic/common')
-rw-r--r--ironic/common/kickstart_utils.py4
-rw-r--r--ironic/common/molds.py6
-rw-r--r--ironic/common/rpc_service.py18
3 files changed, 24 insertions, 4 deletions
diff --git a/ironic/common/kickstart_utils.py b/ironic/common/kickstart_utils.py
index 433cf2390..4e02e2ea7 100644
--- a/ironic/common/kickstart_utils.py
+++ b/ironic/common/kickstart_utils.py
@@ -23,6 +23,7 @@ import pycdlib
import requests
from ironic.common import exception
+from ironic.conf import CONF
LOG = logging.getLogger(__name__)
@@ -107,7 +108,8 @@ def decode_and_extract_config_drive_iso(config_drive_iso_gz):
def _fetch_config_drive_from_url(url):
try:
- config_drive = requests.get(url).content
+ config_drive = requests.get(
+ url, timeout=CONF.webserver_connection_timeout).content
except requests.exceptions.RequestException as e:
raise exception.InstanceDeployFailure(
"Can't download the configdrive content from '%(url)s'. "
diff --git a/ironic/common/molds.py b/ironic/common/molds.py
index 234fcc6e3..a77e42a63 100644
--- a/ironic/common/molds.py
+++ b/ironic/common/molds.py
@@ -49,7 +49,8 @@ def save_configuration(task, url, data):
)
def _request(url, data, auth_header):
return requests.put(
- url, data=json.dumps(data, indent=2), headers=auth_header)
+ url, data=json.dumps(data, indent=2), headers=auth_header,
+ timeout=CONF.webserver_connection_timeout)
auth_header = _get_auth_header(task)
response = _request(url, data, auth_header)
@@ -76,7 +77,8 @@ def get_configuration(task, url):
reraise=True
)
def _request(url, auth_header):
- return requests.get(url, headers=auth_header)
+ return requests.get(url, headers=auth_header,
+ timeout=CONF.webserver_connection_timeout)
auth_header = _get_auth_header(task)
response = _request(url, auth_header)
diff --git a/ironic/common/rpc_service.py b/ironic/common/rpc_service.py
index cb0f23c98..a74f6bab3 100644
--- a/ironic/common/rpc_service.py
+++ b/ironic/common/rpc_service.py
@@ -100,7 +100,8 @@ class RPCService(service.Service):
seconds=CONF.hash_ring_reset_interval)
try:
- self.manager.del_host(deregister=self.deregister)
+ self.manager.del_host(deregister=self.deregister,
+ clear_node_reservations=False)
except Exception as e:
LOG.exception('Service error occurred when cleaning up '
'the RPC manager. Error: %s', e)
@@ -127,6 +128,21 @@ class RPCService(service.Service):
LOG.info('Stopped RPC server for service %(service)s on host '
'%(host)s.',
{'service': self.topic, 'host': self.host})
+
+ # Wait for reservation locks held by this conductor.
+ # The conductor process will end when:
+ # - All reservations for this conductor are released
+ # - CONF.graceful_shutdown_timeout has elapsed
+ # - The process manager (systemd, kubernetes) sends SIGKILL after the
+ # configured graceful period
+ graceful_time = initial_time + datetime.timedelta(
+ seconds=CONF.graceful_shutdown_timeout)
+ while (self.manager.has_reserved()
+ and graceful_time > timeutils.utcnow()):
+ LOG.info('Waiting for reserved nodes to clear on host %(host)s',
+ {'host': self.host})
+ time.sleep(1)
+
rpc.set_global_manager(None)
def _handle_signal(self, signo, frame):