-
Notifications
You must be signed in to change notification settings - Fork 80
/
action.yml
204 lines (187 loc) · 7.96 KB
/
action.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
name: 'Maximize build disk space'
description: 'Maximize the available disk space for your build job'
branding:
icon: 'crop'
color: 'orange'
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.'
required: false
default: '100'
swap-size-mb:
description: 'Swap space to create, in Megabytes.'
required: false
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.
required: false
default: 'false'
build-mount-path:
description: 'Absolute path to the mount point where the build space will be available, defaults to $GITHUB_WORKSPACE if unset.'
required: false
build-mount-path-ownership:
description: 'Ownership of the mount point path, defaults to standard "runner" user and group.'
required: false
default: 'runner:runner'
pv-loop-path:
description: 'Absolute file path for the LVM image created on the root filesystem, the default is usually fine.'
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'
required: false
default: '/mnt/tmp-pv.img'
remove-dotnet:
description: 'Removes .NET runtime and libraries. (frees ~17 GB)'
required: false
default: 'false'
remove-android:
description: 'Removes Android SDKs and Tools. (frees ~11 GB)'
required: false
default: 'false'
remove-haskell:
description: 'Removes GHC (Haskell) artifacts. (frees ~2.7 GB)'
required: false
default: 'false'
remove-codeql:
description: 'Removes CodeQL Action Bundles. (frees ~5.4 GB)'
required: false
default: 'false'
remove-docker-images:
description: 'Removes cached Docker images. (frees ~3 GB)'
required: false
default: 'false'
runs:
using: "composite"
steps:
- name: Disk space report before modification
shell: bash
run: |
echo "Memory and swap:"
sudo free
echo
sudo swapon --show
echo
echo "Available storage:"
sudo 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
- name: Disk space report after modification
shell: bash
run: |
echo "Memory and swap:"
sudo free
echo
sudo swapon --show
echo
echo "Available storage:"
sudo df -h