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:
Joe Gordon
2013-10-14 15:53:59 -07:00
parent 042dc44970
commit 81d35f36e1
2 changed files with 98 additions and 29 deletions

View File

@@ -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():

View File

@@ -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):