Merge "Get disk info from compute_node"
This commit is contained in:
commit
f5f94ec0f1
@ -41,6 +41,10 @@ class NopClaim(object):
|
|||||||
def cpu(self):
|
def cpu(self):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
@property
|
||||||
|
def disk(self):
|
||||||
|
return 0
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@ -93,6 +97,10 @@ class Claim(NopClaim):
|
|||||||
def cpu(self):
|
def cpu(self):
|
||||||
return self.container.cpu or 0
|
return self.container.cpu or 0
|
||||||
|
|
||||||
|
@property
|
||||||
|
def disk(self):
|
||||||
|
return self.container.disk or 0
|
||||||
|
|
||||||
def abort(self):
|
def abort(self):
|
||||||
"""Requiring claimed resources has failed or been aborted."""
|
"""Requiring claimed resources has failed or been aborted."""
|
||||||
LOG.debug("Aborting claim: %s", self)
|
LOG.debug("Aborting claim: %s", self)
|
||||||
@ -116,13 +124,15 @@ class Claim(NopClaim):
|
|||||||
# unlimited:
|
# unlimited:
|
||||||
memory_limit = limits.get('memory')
|
memory_limit = limits.get('memory')
|
||||||
cpu_limit = limits.get('cpu')
|
cpu_limit = limits.get('cpu')
|
||||||
|
disk_limit = limits.get('disk')
|
||||||
|
|
||||||
LOG.info('Attempting claim: memory %(memory)s, '
|
LOG.info('Attempting claim: memory %(memory)s, '
|
||||||
'cpu %(cpu).02f CPU',
|
'cpu %(cpu).02f CPU, disk %(disk)s',
|
||||||
{'memory': self.memory, 'cpu': self.cpu})
|
{'memory': self.memory, 'cpu': self.cpu, 'disk': self.disk})
|
||||||
|
|
||||||
reasons = [self._test_memory(resources, memory_limit),
|
reasons = [self._test_memory(resources, memory_limit),
|
||||||
self._test_cpu(resources, cpu_limit),
|
self._test_cpu(resources, cpu_limit),
|
||||||
|
self._test_disk(resources, disk_limit),
|
||||||
self._test_pci()]
|
self._test_pci()]
|
||||||
# TODO(Shunli): test numa here
|
# TODO(Shunli): test numa here
|
||||||
reasons = [r for r in reasons if r is not None]
|
reasons = [r for r in reasons if r is not None]
|
||||||
@ -156,6 +166,14 @@ class Claim(NopClaim):
|
|||||||
|
|
||||||
return self._test(type_, unit, total, used, requested, limit)
|
return self._test(type_, unit, total, used, requested, limit)
|
||||||
|
|
||||||
|
def _test_disk(self, resources, limit):
|
||||||
|
type_ = _("disk")
|
||||||
|
unit = "GB"
|
||||||
|
total = resources.disk_total
|
||||||
|
used = resources.disk_used
|
||||||
|
requested = self.disk
|
||||||
|
return self._test(type_, unit, total, used, requested, limit)
|
||||||
|
|
||||||
def _test(self, type_, unit, total, used, requested, limit):
|
def _test(self, type_, unit, total, used, requested, limit):
|
||||||
"""Test if the type resource needed for a claim can be allocated."""
|
"""Test if the type resource needed for a claim can be allocated."""
|
||||||
|
|
||||||
|
@ -92,10 +92,10 @@ class ComputeNodeTracker(object):
|
|||||||
be used to revert the resource usage if an error occurs
|
be used to revert the resource usage if an error occurs
|
||||||
during the container build.
|
during the container build.
|
||||||
"""
|
"""
|
||||||
# No memory, cpu, or pci_request specified, no need to claim resource
|
# No memory, cpu, disk or pci_request specified, no need to claim
|
||||||
# now.
|
# resource now.
|
||||||
if not (container.memory or container.cpu or pci_requests):
|
if not (container.memory or container.cpu or pci_requests or
|
||||||
self._set_container_host(context, container)
|
container.disk):
|
||||||
return claims.NopClaim()
|
return claims.NopClaim()
|
||||||
|
|
||||||
# We should have the compute node created here, just get it.
|
# We should have the compute node created here, just get it.
|
||||||
@ -213,6 +213,7 @@ class ComputeNodeTracker(object):
|
|||||||
cn.mem_free = cn.mem_total
|
cn.mem_free = cn.mem_total
|
||||||
cn.mem_used = 0
|
cn.mem_used = 0
|
||||||
cn.running_containers = 0
|
cn.running_containers = 0
|
||||||
|
cn.disk_used = 0
|
||||||
|
|
||||||
for cnt in containers:
|
for cnt in containers:
|
||||||
self._update_usage_from_container(context, cnt)
|
self._update_usage_from_container(context, cnt)
|
||||||
@ -222,10 +223,12 @@ class ComputeNodeTracker(object):
|
|||||||
def _update_usage(self, usage, sign=1):
|
def _update_usage(self, usage, sign=1):
|
||||||
mem_usage = usage['memory']
|
mem_usage = usage['memory']
|
||||||
cpus_usage = usage.get('cpu', 0)
|
cpus_usage = usage.get('cpu', 0)
|
||||||
|
disk_usage = usage['disk']
|
||||||
|
|
||||||
cn = self.compute_node
|
cn = self.compute_node
|
||||||
cn.mem_used += sign * mem_usage
|
cn.mem_used += sign * mem_usage
|
||||||
cn.cpu_used += sign * cpus_usage
|
cn.cpu_used += sign * cpus_usage
|
||||||
|
cn.disk_used += sign * disk_usage
|
||||||
|
|
||||||
# free ram may be negative, depending on policy:
|
# free ram may be negative, depending on policy:
|
||||||
cn.mem_free = cn.mem_total - cn.mem_used
|
cn.mem_free = cn.mem_total - cn.mem_used
|
||||||
@ -294,8 +297,8 @@ class ComputeNodeTracker(object):
|
|||||||
if container.memory:
|
if container.memory:
|
||||||
memory = int(container.memory[:-1])
|
memory = int(container.memory[:-1])
|
||||||
usage = {'memory': memory,
|
usage = {'memory': memory,
|
||||||
'cpu': container.cpu or 0}
|
'cpu': container.cpu or 0,
|
||||||
|
'disk': container.disk or 0}
|
||||||
# update numa usage here
|
# update numa usage here
|
||||||
|
|
||||||
return usage
|
return usage
|
||||||
|
@ -21,6 +21,10 @@ compute_opts = [
|
|||||||
default=True,
|
default=True,
|
||||||
help='restart the containers which are running'
|
help='restart the containers which are running'
|
||||||
'before the host reboots.'),
|
'before the host reboots.'),
|
||||||
|
cfg.FloatOpt(
|
||||||
|
'reserve_disk_for_image',
|
||||||
|
default=0.2,
|
||||||
|
help='reserve disk for docker images'),
|
||||||
]
|
]
|
||||||
|
|
||||||
service_opts = [
|
service_opts = [
|
||||||
|
@ -53,6 +53,9 @@ docker_opts = [
|
|||||||
default=5,
|
default=5,
|
||||||
help='Timeout in seconds for executing a command in a docker '
|
help='Timeout in seconds for executing a command in a docker '
|
||||||
'container.'),
|
'container.'),
|
||||||
|
cfg.StrOpt('docker_data_root',
|
||||||
|
default='/var/lib/docker',
|
||||||
|
help='Root directory of persistent Docker state.'),
|
||||||
]
|
]
|
||||||
|
|
||||||
ALL_OPTS = (docker_opts)
|
ALL_OPTS = (docker_opts)
|
||||||
|
@ -902,6 +902,18 @@ class DockerDriver(driver.ContainerDriver):
|
|||||||
return (total, running, paused, stopped, cpus,
|
return (total, running, paused, stopped, cpus,
|
||||||
architecture, os_type, os, kernel_version, labels)
|
architecture, os_type, os, kernel_version, labels)
|
||||||
|
|
||||||
|
def get_total_disk_for_container(self):
|
||||||
|
try:
|
||||||
|
(output, err) = utils.execute('df', '-B', '1G',
|
||||||
|
CONF.docker.docker_data_root,
|
||||||
|
run_as_root=True)
|
||||||
|
except exception.CommandError:
|
||||||
|
LOG.info('There was a problem while executing df -B 1G %s',
|
||||||
|
CONF.docker.docker_data_root)
|
||||||
|
raise exception.CommandError(cmd='df')
|
||||||
|
total_disk = int(output.split('\n')[1].split()[1])
|
||||||
|
return int(total_disk * (1 - CONF.compute.reserve_disk_for_image))
|
||||||
|
|
||||||
def get_cpu_used(self):
|
def get_cpu_used(self):
|
||||||
cpu_used = 0
|
cpu_used = 0
|
||||||
with docker_utils.docker_client() as docker:
|
with docker_utils.docker_client() as docker:
|
||||||
|
@ -192,6 +192,9 @@ class ContainerDriver(object):
|
|||||||
def get_host_info(self):
|
def get_host_info(self):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def get_total_disk_for_container(self):
|
||||||
|
return NotImplementedError()
|
||||||
|
|
||||||
def get_cpu_used(self):
|
def get_cpu_used(self):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
@ -241,6 +244,8 @@ class ContainerDriver(object):
|
|||||||
cpu_used = self.get_cpu_used()
|
cpu_used = self.get_cpu_used()
|
||||||
node.cpu_used = cpu_used
|
node.cpu_used = cpu_used
|
||||||
node.labels = labels
|
node.labels = labels
|
||||||
|
disk_total = self.get_total_disk_for_container()
|
||||||
|
node.disk_total = disk_total
|
||||||
|
|
||||||
def node_is_available(self, nodename):
|
def node_is_available(self, nodename):
|
||||||
"""Return whether this compute service manages a particular node."""
|
"""Return whether this compute service manages a particular node."""
|
||||||
|
@ -714,13 +714,15 @@ class TestDockerDriver(base.DriverTestCase):
|
|||||||
security_groups=test_sec_group_id)
|
security_groups=test_sec_group_id)
|
||||||
|
|
||||||
@mock.patch('zun.common.utils.execute')
|
@mock.patch('zun.common.utils.execute')
|
||||||
|
@mock.patch('zun.container.docker.driver.DockerDriver'
|
||||||
|
'.get_total_disk_for_container')
|
||||||
@mock.patch('zun.container.driver.ContainerDriver.get_host_mem')
|
@mock.patch('zun.container.driver.ContainerDriver.get_host_mem')
|
||||||
@mock.patch(
|
@mock.patch(
|
||||||
'zun.container.docker.driver.DockerDriver.get_host_info')
|
'zun.container.docker.driver.DockerDriver.get_host_info')
|
||||||
@mock.patch(
|
@mock.patch(
|
||||||
'zun.container.docker.driver.DockerDriver.get_cpu_used')
|
'zun.container.docker.driver.DockerDriver.get_cpu_used')
|
||||||
def test_get_available_resources(self, mock_cpu_used, mock_info, mock_mem,
|
def test_get_available_resources(self, mock_cpu_used, mock_info, mock_mem,
|
||||||
mock_output):
|
mock_disk, mock_output):
|
||||||
self.driver = DockerDriver()
|
self.driver = DockerDriver()
|
||||||
mock_output.return_value = LSCPU_ON
|
mock_output.return_value = LSCPU_ON
|
||||||
conf.CONF.set_override('floating_cpu_set', "0")
|
conf.CONF.set_override('floating_cpu_set', "0")
|
||||||
@ -730,6 +732,7 @@ class TestDockerDriver(base.DriverTestCase):
|
|||||||
'CentOS', '3.10.0-123',
|
'CentOS', '3.10.0-123',
|
||||||
{'dev.type': 'product'})
|
{'dev.type': 'product'})
|
||||||
mock_cpu_used.return_value = 1.0
|
mock_cpu_used.return_value = 1.0
|
||||||
|
mock_disk.return_value = 80
|
||||||
node_obj = objects.ComputeNode()
|
node_obj = objects.ComputeNode()
|
||||||
self.driver.get_available_resources(node_obj)
|
self.driver.get_available_resources(node_obj)
|
||||||
self.assertEqual(_numa_topo_spec, node_obj.numa_topology.to_list())
|
self.assertEqual(_numa_topo_spec, node_obj.numa_topology.to_list())
|
||||||
@ -747,3 +750,4 @@ class TestDockerDriver(base.DriverTestCase):
|
|||||||
self.assertEqual('CentOS', node_obj.os)
|
self.assertEqual('CentOS', node_obj.os)
|
||||||
self.assertEqual('3.10.0-123', node_obj.kernel_version)
|
self.assertEqual('3.10.0-123', node_obj.kernel_version)
|
||||||
self.assertEqual({'dev.type': 'product'}, node_obj.labels)
|
self.assertEqual({'dev.type': 'product'}, node_obj.labels)
|
||||||
|
self.assertEqual(80, node_obj.disk_total)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user