#!/bin/bash

# This takes a PVC name and namespace then flattens the boot disk (to get it off a backed image disk). 
# Exit if there's none provided. 
if [ -z $1 ] &&  [ -z $2 ] [ -z $3 ] [ -z $4 ]; then
        echo "You need to provide a pvcname,  namespace, new-diskname, and storageclass for the disk you want to migrate"
        exit 1
fi


echo "Looking to migrate $1 to $4"

# Get the PVC object related stuff
diskPVC=$(kubectl -n $2 get pvc $1 -o json)
diskSC=$(echo $diskPVC | jq -r .spec.storageClassName)
diskCap=$(echo $diskPVC | jq -r .status.capacity.storage)
defaultSC=$(kubectl get storageclasses.storage.k8s.io  |grep "(default)" | awk '{ print $1}')
vmns=$2

#If the disk mode permits, we might not have to shut it down, but I'd feel better about it if we did.
diskMode=$(kubectl -n $vmns get pvc $vmVolumePVC --no-headers | awk '{ print $5 }')

# Make sure we can actually flatten this and it's currently and image backed SC.
if [ $diskSC == $4 ]; then
        echo "Yoooo.. This disk is already the sane storage class. Exiting."
        exit 1
fi

# Make a new PVC Root-Flat disk.

if [ -n $3 ] ; then
        newDiskName="$3"
else
        newDiskName="$1-flat"
fi

echo "We're going to make a new $diskCap disk called $newDiskName with the $4 StorageClass."

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: $newDiskName
  namespace: $vmns
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: $diskCap
  storageClassName: $4
  volumeMode: Block
EOF

echo -n "Waiting for $newDiskName to be ready..."
while [[ $(kubectl -n $vmns get pvc $newDiskName -o json |jq -r '.metadata.annotations.["pv.kubernetes.io/bind-completed"]' ) != "yes" ]]; do
        echo -n "."
        sleep 3
done

echo ""
echo -n "Creating a job to block copy the disks."
# Mount the PVCs in a pod so we can dd them in a job. 
cat <<EOF | kubectl apply -f -
apiVersion: batch/v1
kind: Job
metadata:
  name: $1-sc-migration
  namespace: $2
spec:
  backoffLimit: 2
  completionMode: NonIndexed
  completions: 1
  parallelism: 1
  template:
    metadata:
      labels:
        job-name: $1-sc-migration
      namespace: $2
    spec:
      dnsPolicy: ClusterFirst
      restartPolicy: Never
      schedulerName: default-scheduler
      terminationGracePeriodSeconds: 30
      containers:
          - name: sak-disk-flattener
            image: supporttools/swiss-army-knife
            command: ["/bin/sh", "-c"]
            args: [ "dd if=/dev/xvdb of=/dev/xvdc status=progress bs=4096" ]
            imagePullPolicy: IfNotPresent
            volumeDevices:
              - name: old-disk
                devicePath: /dev/xvdb
              - name: new-disk
                devicePath: /dev/xvdc
      volumes:
        - name: old-disk
          persistentVolumeClaim:
            claimName: $1
        - name: new-disk
          persistentVolumeClaim:
            claimName: $newDiskName
EOF
echo ""
echo -n "Waiting for $1-sc-migration job to complete..."
sleep 5
while [[ $(kubectl -n $vmns get job $1-sc-migration -o json | jq -r .status.succeeded ) != 1 ]]; do
       echo -n "."
       sleep 5
done

echo ""
echo "The new disk $newDiskName is ready now. You'll probably need to delete the jobs and related pods in $3 before you can delete $1. Good luck!"
                                                                                                                                                                                                                                                                                                            113,1         Bot