Skip to content

Commit

Permalink
Test
Browse files Browse the repository at this point in the history
  • Loading branch information
testableapple committed Sep 2, 2024
1 parent 0840092 commit fb01514
Showing 1 changed file with 116 additions and 128 deletions.
244 changes: 116 additions & 128 deletions .github/actions/disk-space/action.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
name: 'Maximize build disk space'
description: 'Maximize build disk space'
name: 'Maximize build disk space for macOS'
description: 'Maximize build disk space on macOS'
inputs:
root-reserve-mb:
description: 'Space to be left free on the root filesystem, in Megabytes.'
required: false
default: '1024'
temp-reserve-mb:
description: 'Space to be left free on the temp filesystem (/mnt), in Megabytes.'
description: 'Space to be left free on the temp filesystem (/private/tmp), in Megabytes.'
required: false
default: '100'
swap-size-mb:
Expand All @@ -15,9 +15,7 @@ inputs:
default: '4096'
overprovision-lvm:
description: |
Create the LVM disk images as sparse files, making the space required for the LVM image files *appear* unused on the
hosting volumes until actually allocated. Use with care, this can lead to surprising out-of-disk-space situations.
You should prefer adjusting root-reserve-mb/temp-reserve-mb over using this option.
(macOS does not support LVM in the same way as Linux, so this option is not applicable.)
required: false
default: 'false'
build-mount-path:
Expand All @@ -26,15 +24,15 @@ inputs:
build-mount-path-ownership:
description: 'Ownership of the mount point path, defaults to standard "runner" user and group.'
required: false
default: 'runner:runner'
default: 'runner:staff'
pv-loop-path:
description: 'Absolute file path for the LVM image created on the root filesystem, the default is usually fine.'
description: 'Absolute file path for the disk image created on the root filesystem.'
required: false
default: '/pv.img'
tmp-pv-loop-path:
description: 'Absolute file path for the LVM image created on the temp filesystem, the default is usually fine. Must reside on /mnt'
description: 'Absolute file path for the disk image created on the temp filesystem.'
required: false
default: '/mnt/tmp-pv.img'
default: '/private/tmp/tmp-pv.img'
remove-dotnet:
description: 'Removes .NET runtime and libraries. (frees ~17 GB)'
required: false
Expand All @@ -61,135 +59,125 @@ runs:
- name: Disk space report before modification
shell: bash
run: |
echo "Memory and swap:"
vm_stat
echo
echo "Available storage:"
sudo df -h
df -h
echo
- name: Maximize build disk space
shell: bash
run: |
set -euo pipefail
BUILD_MOUNT_PATH="${{ inputs.build-mount-path }}"
if [[ -z "${BUILD_MOUNT_PATH}" ]]; then
BUILD_MOUNT_PATH="${GITHUB_WORKSPACE}"
fi
echo "Arguments:"
echo
echo " Root reserve: ${{ inputs.root-reserve-mb }} MiB"
echo " Temp reserve: ${{ inputs.temp-reserve-mb }} MiB"
echo " Swap space: ${{ inputs.swap-size-mb }} MiB"
echo " Overprovision LVM: ${{ inputs.overprovision-lvm }}"
echo " Mount path: ${BUILD_MOUNT_PATH}"
echo " Root PV loop path: ${{ inputs.pv-loop-path }}"
echo " Temp PV loop path: ${{ inputs.tmp-pv-loop-path }}"
echo -n " Removing: "
if [[ ${{ inputs.remove-dotnet }} == 'true' ]]; then
echo -n "dotnet "
fi
if [[ ${{ inputs.remove-android }} == 'true' ]]; then
echo -n "android "
fi
if [[ ${{ inputs.remove-haskell }} == 'true' ]]; then
echo -n "haskell "
fi
if [[ ${{ inputs.remove-codeql }} == 'true' ]]; then
echo -n "codeql "
fi
if [[ ${{ inputs.remove-docker-images }} == 'true' ]]; then
echo -n "docker "
fi
echo
# store owner of $GITHUB_WORKSPACE in case the action deletes it
WORKSPACE_OWNER="$(stat -c '%U:%G' "${GITHUB_WORKSPACE}")"
# ensure mount path exists before the action
sudo mkdir -p "${BUILD_MOUNT_PATH}"
sudo find "${BUILD_MOUNT_PATH}" -maxdepth 0 ! -empty -exec echo 'WARNING: directory [{}] is not empty, data loss might occur. Content:' \; -exec ls -al "{}" \;
echo "Removing unwanted software... "
if [[ ${{ inputs.remove-dotnet }} == 'true' ]]; then
sudo rm -rf /usr/share/dotnet
fi
if [[ ${{ inputs.remove-android }} == 'true' ]]; then
sudo rm -rf /usr/local/lib/android
fi
if [[ ${{ inputs.remove-haskell }} == 'true' ]]; then
sudo rm -rf /opt/ghc
fi
if [[ ${{ inputs.remove-codeql }} == 'true' ]]; then
sudo rm -rf /opt/hostedtoolcache/CodeQL
fi
if [[ ${{ inputs.remove-docker-images }} == 'true' ]]; then
sudo docker image prune --all --force
fi
echo "... done"
VG_NAME=buildvg
# github runners have an active swap file in /mnt/swapfile
# we want to reuse the temp disk, so first unmount swap and clean the temp disk
echo "Unmounting and removing swap file."
sudo swapoff -a
sudo rm -f /mnt/swapfile
echo "Creating LVM Volume."
echo " Creating LVM PV on root fs."
# create loop pv image on root fs
ROOT_RESERVE_KB=$(expr ${{ inputs.root-reserve-mb }} \* 1024)
ROOT_FREE_KB=$(df --block-size=1024 --output=avail / | tail -1)
ROOT_LVM_SIZE_KB=$(expr $ROOT_FREE_KB - $ROOT_RESERVE_KB)
ROOT_LVM_SIZE_BYTES=$(expr $ROOT_LVM_SIZE_KB \* 1024)
sudo touch "${{ inputs.pv-loop-path }}" && sudo fallocate -z -l "${ROOT_LVM_SIZE_BYTES}" "${{ inputs.pv-loop-path }}"
export ROOT_LOOP_DEV=$(sudo losetup --find --show "${{ inputs.pv-loop-path }}")
sudo pvcreate -f "${ROOT_LOOP_DEV}"
# create pv on temp disk
echo " Creating LVM PV on temp fs."
TMP_RESERVE_KB=$(expr ${{ inputs.temp-reserve-mb }} \* 1024)
TMP_FREE_KB=$(df --block-size=1024 --output=avail /mnt | tail -1)
TMP_LVM_SIZE_KB=$(expr $TMP_FREE_KB - $TMP_RESERVE_KB)
TMP_LVM_SIZE_BYTES=$(expr $TMP_LVM_SIZE_KB \* 1024)
sudo touch "${{ inputs.tmp-pv-loop-path }}" && sudo fallocate -z -l "${TMP_LVM_SIZE_BYTES}" "${{ inputs.tmp-pv-loop-path }}"
export TMP_LOOP_DEV=$(sudo losetup --find --show "${{ inputs.tmp-pv-loop-path }}")
sudo pvcreate -f "${TMP_LOOP_DEV}"
# create volume group from these pvs
sudo vgcreate "${VG_NAME}" "${TMP_LOOP_DEV}" "${ROOT_LOOP_DEV}"
echo "Recreating swap"
# create and activate swap
sudo lvcreate -L "${{ inputs.swap-size-mb }}M" -n swap "${VG_NAME}"
sudo mkswap "/dev/mapper/${VG_NAME}-swap"
sudo swapon "/dev/mapper/${VG_NAME}-swap"
echo "Creating build volume"
# create and mount build volume
sudo lvcreate -l 100%FREE -n buildlv "${VG_NAME}"
if [[ ${{ inputs.overprovision-lvm }} == 'true' ]]; then
sudo mkfs.ext4 -m0 "/dev/mapper/${VG_NAME}-buildlv"
else
sudo mkfs.ext4 -Enodiscard -m0 "/dev/mapper/${VG_NAME}-buildlv"
fi
sudo mount "/dev/mapper/${VG_NAME}-buildlv" "${BUILD_MOUNT_PATH}"
sudo chown -R "${{ inputs.build-mount-path-ownership }}" "${BUILD_MOUNT_PATH}"
# if build mount path is a parent of $GITHUB_WORKSPACE, and has been deleted, recreate it
if [[ ! -d "${GITHUB_WORKSPACE}" ]]; then
sudo mkdir -p "${GITHUB_WORKSPACE}"
sudo chown -R "${WORKSPACE_OWNER}" "${GITHUB_WORKSPACE}"
fi
set -euo pipefail
BUILD_MOUNT_PATH="${{ inputs.build-mount-path }}"
if [[ -z "${BUILD_MOUNT_PATH}" ]]; then
BUILD_MOUNT_PATH="${GITHUB_WORKSPACE}"
fi
echo "Arguments:"
echo
echo " Root reserve: ${{ inputs.root-reserve-mb }} MiB"
echo " Temp reserve: ${{ inputs.temp-reserve-mb }} MiB"
echo " Swap space: ${{ inputs.swap-size-mb }} MiB"
echo " Overprovision LVM: ${{ inputs.overprovision-lvm }} (Not applicable on macOS)"
echo " Mount path: ${BUILD_MOUNT_PATH}"
echo " Root PV loop path: ${{ inputs.pv-loop-path }}"
echo " Temp PV loop path: ${{ inputs.tmp-pv-loop-path }}"
echo -n " Removing: "
if [[ ${{ inputs.remove-dotnet }} == 'true' ]]; then
echo -n "dotnet "
fi
if [[ ${{ inputs.remove-android }} == 'true' ]]; then
echo -n "android "
fi
if [[ ${{ inputs.remove-haskell }} == 'true' ]]; then
echo -n "haskell "
fi
if [[ ${{ inputs.remove-codeql }} == 'true' ]]; then
echo -n "codeql "
fi
if [[ ${{ inputs.remove-docker-images }} == 'true' ]]; then
echo -n "docker "
fi
echo
# store owner of $GITHUB_WORKSPACE in case the action deletes it
WORKSPACE_OWNER="$(stat -f '%Su:%Sg' "${GITHUB_WORKSPACE}")"
echo "Removing unwanted software... "
if [[ ${{ inputs.remove-dotnet }} == 'true' ]]; then
sudo rm -rf /usr/local/share/dotnet
fi
if [[ ${{ inputs.remove-android }} == 'true' ]]; then
sudo rm -rf /usr/local/lib/android
fi
if [[ ${{ inputs.remove-haskell }} == 'true' ]]; then
sudo rm -rf /usr/local/ghc
fi
if [[ ${{ inputs.remove-codeql }} == 'true' ]]; then
sudo rm -rf /usr/local/hostedtoolcache/CodeQL
fi
if [[ ${{ inputs.remove-docker-images }} == 'true' ]]; then
docker image prune --all --force
fi
echo "... done"
# No LVM on macOS, use disk images instead
VG_NAME=buildvg
echo "Creating disk images."
# Create a disk image for the root filesystem
ROOT_RESERVE_KB=$(expr ${{ inputs.root-reserve-mb }} \* 1024)
ROOT_FREE_KB=$(df -k / | tail -1 | awk '{print $4}')
ROOT_LVM_SIZE_KB=$(expr $ROOT_FREE_KB - $ROOT_RESERVE_KB)
hdiutil create -size ${ROOT_LVM_SIZE_KB}k -fs HFS+ -volname "${VG_NAME}-root" "${{ inputs.pv-loop-path }}"
# Create a disk image for the temp filesystem
TMP_RESERVE_KB=$(expr ${{ inputs.temp-reserve-mb }} \* 1024)
TMP_FREE_KB=$(df -k /private/tmp | tail -1 | awk '{print $4}')
TMP_LVM_SIZE_KB=$(expr $TMP_FREE_KB - $TMP_RESERVE_KB)
hdiutil create -size ${TMP_LVM_SIZE_KB}k -fs HFS+ -volname "${VG_NAME}-tmp" "${{ inputs.tmp-pv-loop-path }}"
echo "Attaching disk images."
# Attach and mount disk images
ROOT_DEV=$(hdiutil attach -nobrowse -nomount "${{ inputs.pv-loop-path }}" | awk '{print $1}')
TMP_DEV=$(hdiutil attach -nobrowse -nomount "${{ inputs.tmp-pv-loop-path }}" | awk '{print $1}')
sudo newfs_hfs -v "${VG_NAME}-root" ${ROOT_DEV}
sudo newfs_hfs -v "${VG_NAME}-tmp" ${TMP_DEV}
echo "Creating build volume"
# Mount the root disk image to the build mount path
sudo mount -t hfs ${ROOT_DEV} "${BUILD_MOUNT_PATH}"
sudo chown -R "${{ inputs.build-mount-path-ownership }}" "${BUILD_MOUNT_PATH}"
echo "Recreating swap"
# Create and activate swap (macOS-specific approach)
sudo rm -f /private/var/vm/swapfile
sudo dd if=/dev/zero of=/private/var/vm/swapfile bs=1024k count=${{ inputs.swap-size-mb }}
sudo chmod 600 /private/var/vm/swapfile
sudo /usr/sbin/diskutil secureErase freespace 0 /private/var/vm/swapfile
sudo /usr/bin/env fs_usage | grep swap
# if build mount path is a parent of $GITHUB_WORKSPACE, and has been deleted, recreate it
if [[ ! -d "${GITHUB_WORKSPACE}" ]]; then
sudo mkdir -p "${GITHUB_WORKSPACE}"
sudo chown -R "${WORKSPACE_OWNER}" "${GITHUB_WORKSPACE}"
fi
# Unmount and detach the disk images at the end
sudo umount "${BUILD_MOUNT_PATH}"
hdiutil detach ${ROOT_DEV}
hdiutil detach ${TMP_DEV}
- name: Disk space report after modification
shell: bash
run: |
echo "Memory and swap:"
sudo free
echo
sudo swapon --show
vm_stat
echo
echo "Available storage:"
sudo df -h
df -h

0 comments on commit fb01514

Please sign in to comment.