Make baremetal_deploy_helper understand ephemeral disks
Teach baremetal_deploy_helper how to run sfdisk with ephemeral disks. baremetal_deploy_helper calls default mkfs on the epheral disk. Change-Id: I92d473c34e9a076f5dbcd54be538410b30b10204 Partial-Bug: #1238311 Co-Authored-By: Robert Collins <rbtcollins@hp.com>
This commit is contained in:
@@ -40,6 +40,7 @@ from nova import unit
|
||||
from nova import utils
|
||||
from nova.virt.baremetal import baremetal_states
|
||||
from nova.virt.baremetal import db
|
||||
from nova.virt.disk import api as disk
|
||||
|
||||
|
||||
QUEUE = Queue.Queue()
|
||||
@@ -83,14 +84,19 @@ def logout_iscsi(portal_address, portal_port, target_iqn):
|
||||
check_exit_code=[0])
|
||||
|
||||
|
||||
def make_partitions(dev, root_mb, swap_mb):
|
||||
"""Create partitions for root and swap on a disk device."""
|
||||
def make_partitions(dev, root_mb, swap_mb, ephemeral_mb):
|
||||
"""Create partitions for root, ephemeral and swap on a disk device."""
|
||||
# Lead in with 1MB to allow room for the partition table itself, otherwise
|
||||
# the way sfdisk adjusts doesn't shift the partition up to compensate, and
|
||||
# we lose the space.
|
||||
# http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/raring/util-linux/
|
||||
# raring/view/head:/fdisk/sfdisk.c#L1940
|
||||
stdin_command = ('1,%d,83;\n,%d,82;\n0,0;\n0,0;\n' % (root_mb, swap_mb))
|
||||
if ephemeral_mb:
|
||||
stdin_command = ('1,%d,83;\n,%d,82;\n,%d,83;\n0,0;\n' %
|
||||
(ephemeral_mb, swap_mb, root_mb))
|
||||
else:
|
||||
stdin_command = ('1,%d,83;\n,%d,82;\n0,0;\n0,0;\n' %
|
||||
(root_mb, swap_mb))
|
||||
utils.execute('sfdisk', '-uM', dev, process_input=stdin_command,
|
||||
run_as_root=True,
|
||||
attempts=3,
|
||||
@@ -125,6 +131,11 @@ def mkswap(dev, label='swap1'):
|
||||
check_exit_code=[0])
|
||||
|
||||
|
||||
def mkfs_ephemeral(dev, label="ephemeral0"):
|
||||
#TODO(jogo) support non-default mkfs options as well
|
||||
disk.mkfs("default", label, dev)
|
||||
|
||||
|
||||
def block_uuid(dev):
|
||||
"""Get UUID of a block device."""
|
||||
out, _ = utils.execute('blkid', '-s', 'UUID', '-o', 'value', dev,
|
||||
@@ -173,15 +184,20 @@ def get_image_mb(image_path):
|
||||
return image_mb
|
||||
|
||||
|
||||
def work_on_disk(dev, root_mb, swap_mb, image_path):
|
||||
def work_on_disk(dev, root_mb, swap_mb, ephemeral_mb, image_path):
|
||||
"""Creates partitions and write an image to the root partition."""
|
||||
root_part = "%s-part1" % dev
|
||||
swap_part = "%s-part2" % dev
|
||||
if ephemeral_mb:
|
||||
ephemeral_part = "%s-part1" % dev
|
||||
swap_part = "%s-part2" % dev
|
||||
root_part = "%s-part3" % dev
|
||||
else:
|
||||
root_part = "%s-part1" % dev
|
||||
swap_part = "%s-part2" % dev
|
||||
|
||||
if not is_block_device(dev):
|
||||
LOG.warn(_("parent device '%s' not found"), dev)
|
||||
return
|
||||
make_partitions(dev, root_mb, swap_mb)
|
||||
make_partitions(dev, root_mb, swap_mb, ephemeral_mb)
|
||||
if not is_block_device(root_part):
|
||||
LOG.warn(_("root device '%s' not found"), root_part)
|
||||
return
|
||||
@@ -190,6 +206,10 @@ def work_on_disk(dev, root_mb, swap_mb, image_path):
|
||||
return
|
||||
dd(image_path, root_part)
|
||||
mkswap(swap_part)
|
||||
if ephemeral_mb and not is_block_device(ephemeral_part):
|
||||
LOG.warn(_("ephemeral device '%s' not found"), ephemeral_part)
|
||||
elif ephemeral_mb:
|
||||
mkfs_ephemeral(ephemeral_part)
|
||||
|
||||
try:
|
||||
root_uuid = block_uuid(root_part)
|
||||
@@ -200,7 +220,7 @@ def work_on_disk(dev, root_mb, swap_mb, image_path):
|
||||
|
||||
|
||||
def deploy(address, port, iqn, lun, image_path, pxe_config_path,
|
||||
root_mb, swap_mb):
|
||||
root_mb, swap_mb, ephemeral_mb):
|
||||
"""All-in-one function to deploy a node."""
|
||||
dev = get_dev(address, port, iqn, lun)
|
||||
image_mb = get_image_mb(image_path)
|
||||
@@ -209,7 +229,8 @@ def deploy(address, port, iqn, lun, image_path, pxe_config_path,
|
||||
discovery(address, port)
|
||||
login_iscsi(address, port, iqn)
|
||||
try:
|
||||
root_uuid = work_on_disk(dev, root_mb, swap_mb, image_path)
|
||||
root_uuid = work_on_disk(dev, root_mb, swap_mb, ephemeral_mb,
|
||||
image_path)
|
||||
except processutils.ProcessExecutionError as err:
|
||||
with excutils.save_and_reraise_exception():
|
||||
# Log output if there was a error
|
||||
@@ -314,6 +335,7 @@ class BareMetalDeploy(object):
|
||||
'pxe_config_path': d['pxe_config_path'],
|
||||
'root_mb': int(d['root_mb']),
|
||||
'swap_mb': int(d['swap_mb']),
|
||||
'ephemeral_mb': int(d['ephemeral_mb']),
|
||||
}
|
||||
# Restart worker, if needed
|
||||
if not self.worker.isAlive():
|
||||
|
||||
@@ -136,22 +136,7 @@ class PhysicalWorkTestCase(test.NoDBTestCase):
|
||||
|
||||
self.stubs.Set(time, 'sleep', noop)
|
||||
|
||||
def test_deploy(self):
|
||||
"""Check loosely all functions are called with right args."""
|
||||
address = '127.0.0.1'
|
||||
port = 3306
|
||||
iqn = 'iqn.xyz'
|
||||
lun = 1
|
||||
image_path = '/tmp/xyz/image'
|
||||
pxe_config_path = '/tmp/abc/pxeconfig'
|
||||
root_mb = 128
|
||||
swap_mb = 64
|
||||
|
||||
dev = '/dev/fake'
|
||||
root_part = '/dev/fake-part1'
|
||||
swap_part = '/dev/fake-part2'
|
||||
root_uuid = '12345678-1234-1234-12345678-12345678abcdef'
|
||||
|
||||
def _deploy_mox(self):
|
||||
self.mox.StubOutWithMock(bmdh, 'get_dev')
|
||||
self.mox.StubOutWithMock(bmdh, 'get_image_mb')
|
||||
self.mox.StubOutWithMock(bmdh, 'discovery')
|
||||
@@ -165,12 +150,30 @@ class PhysicalWorkTestCase(test.NoDBTestCase):
|
||||
self.mox.StubOutWithMock(bmdh, 'switch_pxe_config')
|
||||
self.mox.StubOutWithMock(bmdh, 'notify')
|
||||
|
||||
def test_deploy_no_ephemeral(self):
|
||||
address = '127.0.0.1'
|
||||
port = 3306
|
||||
iqn = 'iqn.xyz'
|
||||
lun = 1
|
||||
image_path = '/tmp/xyz/image'
|
||||
pxe_config_path = '/tmp/abc/pxeconfig'
|
||||
root_mb = 128
|
||||
swap_mb = 64
|
||||
ephemeral_mb = 0
|
||||
|
||||
dev = '/dev/fake'
|
||||
root_part = '/dev/fake-part1'
|
||||
swap_part = '/dev/fake-part2'
|
||||
root_uuid = '12345678-1234-1234-12345678-12345678abcdef'
|
||||
|
||||
self._deploy_mox()
|
||||
|
||||
bmdh.get_dev(address, port, iqn, lun).AndReturn(dev)
|
||||
bmdh.get_image_mb(image_path).AndReturn(1) # < root_mb
|
||||
bmdh.discovery(address, port)
|
||||
bmdh.login_iscsi(address, port, iqn)
|
||||
bmdh.is_block_device(dev).AndReturn(True)
|
||||
bmdh.make_partitions(dev, root_mb, swap_mb)
|
||||
bmdh.make_partitions(dev, root_mb, swap_mb, ephemeral_mb)
|
||||
bmdh.is_block_device(root_part).AndReturn(True)
|
||||
bmdh.is_block_device(swap_part).AndReturn(True)
|
||||
bmdh.dd(image_path, root_part)
|
||||
@@ -182,7 +185,50 @@ class PhysicalWorkTestCase(test.NoDBTestCase):
|
||||
self.mox.ReplayAll()
|
||||
|
||||
bmdh.deploy(address, port, iqn, lun, image_path, pxe_config_path,
|
||||
root_mb, swap_mb)
|
||||
root_mb, swap_mb, ephemeral_mb)
|
||||
|
||||
self.mox.VerifyAll()
|
||||
|
||||
def test_deploy_with_ephemeral(self):
|
||||
address = '127.0.0.1'
|
||||
port = 3306
|
||||
iqn = 'iqn.xyz'
|
||||
lun = 1
|
||||
image_path = '/tmp/xyz/image'
|
||||
pxe_config_path = '/tmp/abc/pxeconfig'
|
||||
root_mb = 128
|
||||
swap_mb = 64
|
||||
ephemeral_mb = 256
|
||||
|
||||
dev = '/dev/fake'
|
||||
ephemeral_part = '/dev/fake-part1'
|
||||
swap_part = '/dev/fake-part2'
|
||||
root_part = '/dev/fake-part3'
|
||||
root_uuid = '12345678-1234-1234-12345678-12345678abcdef'
|
||||
|
||||
self._deploy_mox()
|
||||
self.mox.StubOutWithMock(bmdh, 'mkfs_ephemeral')
|
||||
|
||||
bmdh.get_dev(address, port, iqn, lun).AndReturn(dev)
|
||||
bmdh.get_image_mb(image_path).AndReturn(1) # < root_mb
|
||||
bmdh.discovery(address, port)
|
||||
bmdh.login_iscsi(address, port, iqn)
|
||||
bmdh.is_block_device(dev).AndReturn(True)
|
||||
bmdh.make_partitions(dev, root_mb, swap_mb, ephemeral_mb)
|
||||
bmdh.is_block_device(root_part).AndReturn(True)
|
||||
bmdh.is_block_device(swap_part).AndReturn(True)
|
||||
bmdh.is_block_device(ephemeral_part).AndReturn(True)
|
||||
bmdh.dd(image_path, root_part)
|
||||
bmdh.mkswap(swap_part)
|
||||
bmdh.mkfs_ephemeral(ephemeral_part)
|
||||
bmdh.block_uuid(root_part).AndReturn(root_uuid)
|
||||
bmdh.logout_iscsi(address, port, iqn)
|
||||
bmdh.switch_pxe_config(pxe_config_path, root_uuid)
|
||||
bmdh.notify(address, 10000)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
bmdh.deploy(address, port, iqn, lun, image_path, pxe_config_path,
|
||||
root_mb, swap_mb, ephemeral_mb)
|
||||
|
||||
self.mox.VerifyAll()
|
||||
|
||||
@@ -196,6 +242,7 @@ class PhysicalWorkTestCase(test.NoDBTestCase):
|
||||
pxe_config_path = '/tmp/abc/pxeconfig'
|
||||
root_mb = 128
|
||||
swap_mb = 64
|
||||
ephemeral_mb = 256
|
||||
|
||||
dev = '/dev/fake'
|
||||
|
||||
@@ -213,7 +260,7 @@ class PhysicalWorkTestCase(test.NoDBTestCase):
|
||||
bmdh.get_image_mb(image_path).AndReturn(1) # < root_mb
|
||||
bmdh.discovery(address, port)
|
||||
bmdh.login_iscsi(address, port, iqn)
|
||||
bmdh.work_on_disk(dev, root_mb, swap_mb, image_path).\
|
||||
bmdh.work_on_disk(dev, root_mb, swap_mb, ephemeral_mb, image_path).\
|
||||
AndRaise(TestException)
|
||||
bmdh.logout_iscsi(address, port, iqn)
|
||||
self.mox.ReplayAll()
|
||||
@@ -221,7 +268,7 @@ class PhysicalWorkTestCase(test.NoDBTestCase):
|
||||
self.assertRaises(TestException,
|
||||
bmdh.deploy,
|
||||
address, port, iqn, lun, image_path,
|
||||
pxe_config_path, root_mb, swap_mb)
|
||||
pxe_config_path, root_mb, swap_mb, ephemeral_mb)
|
||||
|
||||
|
||||
class SwitchPxeConfigTestCase(test.NoDBTestCase):
|
||||
|
||||
Reference in New Issue
Block a user