From 2d341c7f0d14bdac90156a7cb483ec562ec8d9e9 Mon Sep 17 00:00:00 2001
From: Shivanand Tendulker <stendulker@gmail.com>
Date: Thu, 20 Aug 2015 03:19:14 -0700
Subject: [PATCH] Fixes config drive creation failure in UEFI boot mode

This fix enables creation of config drive for UEFI only whole disk
images.
It will not work with the hybrid images that support booting in BIOS
and UEFI boot mode.

Change-Id: Ib4dd8c082a50e1dbaf0df91477b062716cb780ff
Closes-Bug: #1486887
Depends-On: I81400305f166d62aa4612aab54602abb8178b64c
---
 Dockerfile                                    |  2 +-
 .../shell/copy_configdrive_to_disk.sh         | 42 ++++++++++++++++---
 2 files changed, 37 insertions(+), 7 deletions(-)

diff --git a/Dockerfile b/Dockerfile
index 9cf9d99d6..c9d671a85 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -13,7 +13,7 @@ RUN echo 'APT::Default-Release "jessie";' > /etc/apt/apt.conf.d/10default && \
 # image on disk
 RUN apt-get update && \
     apt-get -y upgrade && \
-    apt-get install -y --no-install-recommends python2.7 python2.7-dev \
+    apt-get install -y --no-install-recommends gdisk python2.7 python2.7-dev \
         python-pip qemu-utils parted hdparm util-linux genisoimage git gcc \
         bash coreutils tgt dmidecode ipmitool && \
     apt-get --only-upgrade -t testing install -y qemu-utils
diff --git a/ironic_python_agent/shell/copy_configdrive_to_disk.sh b/ironic_python_agent/shell/copy_configdrive_to_disk.sh
index 1095a6d02..8b74e29de 100755
--- a/ironic_python_agent/shell/copy_configdrive_to_disk.sh
+++ b/ironic_python_agent/shell/copy_configdrive_to_disk.sh
@@ -35,6 +35,8 @@ usage() {
   exit 1
 }
 
+MAX_DISK_PARTITIONS=128
+
 CONFIGDRIVE="$1"
 DEVICE="$2"
 
@@ -57,13 +59,41 @@ if [[ $? == 0 ]]; then
   log "Existing configdrive found on ${DEVICE} at ${EXISTING_PARTITION}"
   ISO_PARTITION=$EXISTING_PARTITION
 else
-  # Create small partition at the end of the device
-  log "Adding configdrive partition to $DEVICE"
-  parted -a optimal -s -- $DEVICE mkpart primary ext2 -64MiB -0 || fail "creating configdrive on ${DEVICE}"
 
-  # Find partition we just created
-  # Dump all partitions, ignore empty ones, then get the last partition ID
-  ISO_PARTITION=`sfdisk --dump $DEVICE | grep -v ' 0,' | tail -n1 | awk '{print $1}'` || fail "finding ISO partition created on ${DEVICE}"
+  # Check if it is GPT partition and needs to be re-sized
+  partprobe $DEVICE print 2>&1 | grep "fix the GPT to use all of the space"
+  if [[ $? == 0 ]]; then
+    log "Fixing GPT to use all of the space on device $DEVICE"
+    sgdisk -e $DEVICE || fail "move backup GPT data structures to the end of ${DEVICE}"
+
+    # Need to create new partition for config drive
+    # Not all images have partion numbers in a sequential numbers. There are holes.
+    # These holes get filled up when a new partition is created.
+    TEMP_DIR="$(mktemp -d)"
+    EXISTING_PARTITION_LIST=$TEMP_DIR/existing_partitions
+    UPDATED_PARTITION_LIST=$TEMP_DIR/updated_partitions
+
+    gdisk -l $DEVICE | grep -A$MAX_DISK_PARTITIONS "Number  Start" | grep -v "Number  Start" > $EXISTING_PARTITION_LIST
+
+    # Create small partition at the end of the device
+    log "Adding configdrive partition to $DEVICE"
+    sgdisk -n 0:-64MB:0 $DEVICE || fail "creating configdrive on ${DEVICE}"
+
+    gdisk -l $DEVICE | grep -A$MAX_DISK_PARTITIONS "Number  Start" | grep -v "Number  Start" > $UPDATED_PARTITION_LIST
+
+    CONFIG_PARTITION_ID=`diff $EXISTING_PARTITION_LIST $UPDATED_PARTITION_LIST | tail -n1 |awk '{print $2}'`
+    ISO_PARTITION="${DEVICE}${CONFIG_PARTITION_ID}"
+  else
+    log "Working on MBR only device $DEVICE"
+
+    # Create small partition at the end of the device
+    log "Adding configdrive partition to $DEVICE"
+    parted -a optimal -s -- $DEVICE mkpart primary ext2 -64MiB -0 || fail "creating configdrive on ${DEVICE}"
+
+    # Find partition we just created
+    # Dump all partitions, ignore empty ones, then get the last partition ID
+    ISO_PARTITION=`sfdisk --dump $DEVICE | grep -v ' 0,' | tail -n1 | awk '{print $1}'` || fail "finding ISO partition created on ${DEVICE}"
+  fi
 fi
 
 # This writes the ISO image to the config drive.