├── LICENSE ├── CHANGELOG.md ├── README.md ├── .github └── workflows │ └── test.yaml └── action.yml /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Markus Dobel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [v4] - 2021-03-25: Do not overprovision space by default 4 | 5 | ### Added 6 | 7 | - Configuration option of overprovisioning the build volume (`overprovision-lvm`), defaulting to `'false'`. 8 | - Configurable temp volume reserve (`temp-reserve-mb`), defaulting to `'100'`. 9 | 10 | ### Changed 11 | 12 | - (potentially breaking) The LVM image files are not created sparsely anymore. Previously, free disk space *appeared* free on **both** the build volume and the hosting volume, until actually allocated by writing to the build volume. Now, the space is actually consumed on volume creation -- meaning, that after creating the build volume, the root and temp volume do not have or show more space available than configured in `root-reserve-mb` and `temp-reserve-mb`. This can be reverted by setting `overprovision-lvm` to `'true'`, but surprising out-of-disk space situations might be the result. 13 | - Temp volume reserve was fixed to 1024 KB, this defaults to a more cautious 100 MB now, and is configurable. 14 | 15 | ## [v3] - 2021-02-15: Fix running on Ubuntu 20.04 16 | 17 | ### Changed 18 | 19 | - Includes a workaround for the temp disk being locked on Ubuntu 20.04. Instead of formatting the temp disk, the LVM volume is now created ontop of loop-mounted files on both / and /mnt, leaving the original file systems intact. 20 | 21 | ## [v2] - 2021-01-05: Fix file system permissions on logical volume 22 | 23 | ### Changed 24 | 25 | - Change the owner of the logical volume to the runner user recursively, fixing permission issues when e.g. checking out code to the root of the logical volume. (Actually, the problem is the lost+found folder in the ext4 root, and chowning it breaks its purpose. But since the volume is temporary anyway, lost+found functionality is not really needed). 26 | 27 | ## [v1] - 2020-08-20: Initial release 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Maximize available disk space for build tasks 2 | 3 | By default, public shared Github runners come with around 25-29 GB of free disk space to be consumed by your build job. 4 | If this is too little for you, and your build job runs out of disk space, this action might be for you. 5 | 6 | If not: please go on, there's nothing to see here. 7 | 8 | This action maximizes the available disk space on public shared GitHub runners, by 9 | 10 | - Utilizing space on an otherwise unused temp disk 11 | - Optionally removing unnecessary preinstalled software 12 | - Optionally resizing the SWAP space 13 | 14 | Depending on the use case, you can gain more than double the original space. 15 | 16 | The idea came up when I tried to build a Fedora Linux Kernel RPM on Github, and the Job aborted due to disk space issues. 17 | 18 | ## Caveats 19 | 20 | - **This action is a hack, really**, and on a "works for me" basis. It has been built by reverse-enginnering undocumented parts of the Github runner setup, which might change in the future -- up to the point where this action ceases to work. For sure you're voiding the warranty on Github runners when using this. **If you are not running into disk space issues with the default runner setup, don't use it.**. 21 | - Since this action uses LVM on top of loop-mounted files, expect a space/speed trade-off when using it. I did not measure the speed of the disk, so I do not have numbers, but be warned. 22 | - This action fills the whole root and temp volume with large image files. You will not have more space on the root volume available than specified in `root-reserve-mb`, similarly for `/mnt` and `temp-reserve-mb`. While your build job will usually run (and consume disk space) in `$GITHUB_WORKSPACE` mostly, other parts might require additional space in other places -- e.g. `/var/lib/docker` for docker images, when running docker build steps, but also `apt install` will install to the root volume. Increase `root-reserve-mb` or `temp-reserve-mb` accordingly in these cases -- or set `overprovision-lvm` to true. 23 | - Removal of unnecessary software is currently implemented by `rm -rf` on specific folders, not by using a package manager or anything sophisticated. While this is quick and easy, it might delete dependencies that are required by your job and so break your build (e.g. because your build job uses a .NET based tool and you removed the required runtime). 24 | 25 | Btw: the choice of removable packages is not an expression of dislike against these -- they were just the largest folders for a single toolkit I could find quickly. 26 | 27 | ## How it works 28 | 29 | At the time of writing, public [Github-hosted runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners) are using [Azure DS2_v2 virtual machines](https://docs.microsoft.com/en-us/azure/virtual-machines/dv2-dsv2-series#dsv2-series), featuring a 84GB OS disk on `/` and a 14GB temp disk mounted on `/mnt`. 30 | 31 | 1. The root file system has ~29GB (of 84GB) available, the rest being consumed by the preinstalled build environment. Github runners come with a rich choice of software, see the image descriptions for [Ubuntu 18.04](https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu1804-README.md) or [Ubuntu 20.04](https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-README.md). This is great to support a wide variety of workflows out of the box, but also consumes a lot of space by providing programs that might be unnecessary for an individual build job. 32 | 1. The temp disk mainly hosts a 4GB swap file, leaving approx. 10GB completely unused. 33 | 34 | This action does the following: 35 | 36 | 1. (Optionally) removes unwanted preinstalled software 37 | 1. Concatenates the free space on `/` and `/mnt` (the temp disk) to an LVM volume group 38 | 1. Creates a swap partition and a build volume on that volume group 39 | 1. Mounts the build volume back to a given path (`${GITHUB_WORKSPACE}` by default) 40 | 41 | This results in the space of the previously installed packages and the temp disk being available for your build job. 42 | 43 | ## Usage 44 | 45 | You should most probably use this action as the first build step, even **before** `actions/checkout`. Since this action mounts a volume over the current working directory by default, the current content of the working directory will be inaccessible afterwards. 46 | 47 | With the default configuration, you're gaining about 7-8 GB of disk space. You can trade in swap space or disk reserve to get more and remove software that is unnecessary for your build job (see [this table](https://github.com/easimon/maximize-build-space/blob/test-report/README.md) for examples and the expectable amount of space. 48 | 49 | When removing software, consider that the removal of large amounts of files (which this is) can take minutes to complete. On the upside, you'll get more than 60 GB of disk space available if you actually need it. 50 | 51 | ```yaml 52 | name: My build action requiring more space 53 | on: push 54 | 55 | jobs: 56 | build: 57 | name: Build my artifact 58 | runs-on: ubuntu-latest 59 | steps: 60 | - name: Maximize build space 61 | uses: easimon/maximize-build-space@master 62 | with: 63 | root-reserve-mb: 512 64 | swap-size-mb: 1024 65 | remove-dotnet: 'true' 66 | - name: Checkout 67 | uses: actions/checkout@v3 68 | 69 | - name: Build 70 | run: | 71 | echo "Free space:" 72 | df -h 73 | ``` 74 | 75 | ## Inputs 76 | 77 | All inputs are optional and default to the following, gaining about 7-8 GB additional space. 78 | 79 | ```yaml 80 | root-reserve-mb: 81 | description: 'Space to be left free on the root filesystem, in Megabytes.' 82 | required: false 83 | default: '1024' 84 | temp-reserve-mb: 85 | description: 'Space to be left free on the temp filesystem (/mnt), in Megabytes.' 86 | required: false 87 | default: '100' 88 | swap-size-mb: 89 | description: 'Swap space to create, in Megabytes.' 90 | required: false 91 | default: '4096' 92 | overprovision-lvm: 93 | description: | 94 | Create the LVM disk images as sparse files, making the space required for the LVM image files *appear* unused on the 95 | hosting volumes until actually allocated. Use with care, this can lead to surprising out-of-disk-space situations. 96 | You should prefer adjusting root-reserve-mb/temp-reserve-mb over using this option. 97 | required: false 98 | default: 'false' 99 | build-mount-path: 100 | description: 'Absolute path to the mount point where the build space will be available, defaults to $GITHUB_WORKSPACE if unset.' 101 | required: false 102 | pv-loop-path: 103 | description: 'Absolute file path for the LVM image created on the root filesystem, the default is usually fine.' 104 | required: false 105 | default: '/pv.img' 106 | tmp-pv-loop-path: 107 | description: 'Absolute file path for the LVM image created on the temp filesystem, the default is usually fine. Must reside on /mnt' 108 | required: false 109 | default: '/mnt/tmp-pv.img' 110 | remove-dotnet: 111 | description: 'Removes .NET runtime and libraries.' 112 | required: false 113 | default: 'false' 114 | remove-android: 115 | description: 'Removes Android SDKs and Tools.' 116 | required: false 117 | default: 'false' 118 | remove-haskell: 119 | description: 'Removes GHC (Haskell) artifacts.' 120 | required: false 121 | default: 'false' 122 | remove-codeql: 123 | description: 'Removes CodeQL Action Bundles.' 124 | required: false 125 | default: 'false' 126 | remove-docker-images: 127 | description: 'Removes cached Docker images.' 128 | required: false 129 | default: 'false' 130 | ``` 131 | -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | # weekly, randomly chosen time 6 | - cron: "17 18 * * 0" 7 | push: 8 | branches-ignore: 9 | - 'test-report' 10 | 11 | concurrency: 12 | group: ${{ github.workflow }} 13 | cancel-in-progress: true 14 | 15 | env: 16 | REPORT_DIR: /tmp/build-report 17 | 18 | jobs: 19 | test-docker-tmp: 20 | name: Test removing root-owned folder 21 | runs-on: ubuntu-latest 22 | steps: 23 | - name: Check out Maximize Build Space action 24 | uses: actions/checkout@v4 25 | with: 26 | path: ./.github/actions/maximize-test 27 | 28 | - name: Maximize build space 29 | uses: ./.github/actions/maximize-test 30 | with: 31 | build-mount-path: /var/lib/docker/tmp 32 | 33 | test-mount-parent-of-workspace: 34 | name: Test mounting the parent of GITHUB_WORKSPACE 35 | runs-on: ubuntu-latest 36 | steps: 37 | - name: Check out Maximize Build Space action 38 | uses: actions/checkout@v4 39 | with: 40 | path: ./.github/actions/maximize-test 41 | 42 | - name: Calculate parent of workspace 43 | id: workspace-parent 44 | run: echo "parent=$(dirname "${GITHUB_WORKSPACE}")" >> "$GITHUB_OUTPUT" 45 | 46 | - name: Maximize build space 47 | uses: ./.github/actions/maximize-test 48 | with: 49 | build-mount-path: ${{ steps.workspace-parent.outputs.parent }} 50 | 51 | - name: Create file in build folder as runner user (test ownership) 52 | run: | 53 | mkdir -p ${{ steps.workspace-parent.outputs.parent }}/new 54 | touch ${{ steps.workspace-parent.outputs.parent }}/new/file.txt 55 | touch ${GITHUB_WORKSPACE}/file.txt 56 | ls -alR ${{ steps.workspace-parent.outputs.parent }} 57 | 58 | determine-free-space: 59 | name: Determine free space with different settings 60 | runs-on: ${{ matrix.os }} 61 | 62 | strategy: 63 | fail-fast: false 64 | matrix: 65 | os: 66 | - ubuntu-20.04 67 | - ubuntu-22.04 68 | remove-android: 69 | - 'true' 70 | - 'false' 71 | remove-dotnet: 72 | - 'true' 73 | - 'false' 74 | remove-haskell: 75 | - 'true' 76 | - 'false' 77 | remove-codeql: 78 | - 'true' 79 | - 'false' 80 | remove-docker-images: 81 | - 'true' 82 | - 'false' 83 | 84 | steps: 85 | - name: Record start time 86 | run: | 87 | echo "START_TIME=$(date +%s)" >> $GITHUB_ENV 88 | 89 | - name: Determine free space before 90 | run: | 91 | echo "FREE_GIG_BEFORE=$(df --output=avail --sync -BG "${{ github.workspace }}" | tail -1 | sed 's/[^0-9]*//g')" >> $GITHUB_ENV 92 | 93 | - name: Check out Maximize Build Space action 94 | uses: actions/checkout@v4 95 | with: 96 | path: ./.github/actions/maximize-test 97 | 98 | - name: Maximize build space 99 | uses: ./.github/actions/maximize-test 100 | with: 101 | remove-android: ${{ matrix.remove-android }} 102 | remove-dotnet: ${{ matrix.remove-dotnet }} 103 | remove-haskell: ${{ matrix.remove-haskell }} 104 | remove-codeql: ${{ matrix.remove-codeql }} 105 | remove-docker-images: ${{ matrix.remove-docker-images }} 106 | 107 | - name: Record end time 108 | run: | 109 | echo "END_TIME=$(date +%s)" >> $GITHUB_ENV 110 | 111 | - name: Determine free space after 112 | run: | 113 | echo "FREE_GIG_AFTER=$(df --output=avail --sync -BG "${{ github.workspace }}" | tail -1 | sed 's/[^0-9]*//g')" >> $GITHUB_ENV 114 | 115 | - name: Calculate freed space and elapsed time 116 | run: | 117 | REPORT_FILENAME_BASE="${REPORT_DIR}/${{ matrix.os }}_${{ matrix.remove-android }}_${{ matrix.remove-dotnet }}_${{ matrix.remove-haskell }}_${{ matrix.remove-codeql }}_${{ matrix.remove-docker-images }}" 118 | FREED_GIG=$(expr ${FREE_GIG_AFTER} - ${FREE_GIG_BEFORE}) 119 | ELAPSED_TIME=$(expr ${END_TIME} - ${START_TIME}) 120 | 121 | echo "Free space before: ${FREE_GIG_BEFORE}G" 122 | echo "Free space after : ${FREE_GIG_AFTER}G" 123 | echo "Space freed : ${FREED_GIG}G" 124 | echo "Time elapsed : ${ELAPSED_TIME} seconds" 125 | 126 | mkdir -p "${REPORT_DIR}" 127 | 128 | REMOVE_ANDROID="${{ matrix.remove-android }}" 129 | REMOVE_DOTNET="${{ matrix.remove-dotnet }}" 130 | REMOVE_HASKELL="${{ matrix.remove-haskell }}" 131 | REMOVE_CODEQL="${{ matrix.remove-codeql }}" 132 | REMOVE_DOCKER_IMAGES="${{ matrix.remove-docker-images }}" 133 | 134 | cat < "${REPORT_FILENAME_BASE}.json" 135 | { 136 | "os": "${{ matrix.os }}", 137 | "remove_android": "${REMOVE_ANDROID//false/}", 138 | "remove_dotnet": "${REMOVE_DOTNET//false/}", 139 | "remove_haskell": "${REMOVE_HASKELL//false/}", 140 | "remove_codeql": "${REMOVE_CODEQL//false/}", 141 | "remove_docker_images": "${REMOVE_DOCKER_IMAGES//false/}", 142 | "space_free_before": "${FREE_GIG_BEFORE}", 143 | "space_free_after": "${FREE_GIG_AFTER}", 144 | "space_freed": "${FREED_GIG}", 145 | "elapsed_time": "${ELAPSED_TIME}" 146 | } 147 | EOF 148 | jq -r '[.os, .remove_android, .remove_dotnet, .remove_haskell, .remove_codeql, .remove_docker_images, .space_freed, .space_free_after, .elapsed_time] | join(" | ")' < "${REPORT_FILENAME_BASE}.json" >> "${REPORT_FILENAME_BASE}.txt" 149 | 150 | - name: Upload disk space report 151 | uses: actions/upload-artifact@v3 152 | with: 153 | name: disk-space-report-single 154 | path: ${{ env.REPORT_DIR }} 155 | 156 | collect-reports: 157 | name: Collect reports 158 | runs-on: ubuntu-latest 159 | needs: determine-free-space 160 | env: 161 | REPORT_FILE: space-free-report.md 162 | 163 | steps: 164 | - name: Download single reports 165 | uses: actions/download-artifact@v3 166 | with: 167 | name: disk-space-report-single 168 | path: ${{ env.REPORT_DIR }} 169 | 170 | - name: Join Markdown report 171 | run: | 172 | echo 'OS | Android SDKs removed | .NET SDKs removed | Haskell removed | CodeQL Removed | Cached Docker Images Removed | GB freed | GB free | Elapsed Time (seconds) |' > "${REPORT_DIR}/${REPORT_FILE}" 173 | echo '---|:--------------------:|:-----------------:|:---------------:|:--------------:|:----------------------------:|:--------:|:-------:|:----------------------:|' >> "${REPORT_DIR}/${REPORT_FILE}" 174 | cat ${REPORT_DIR}/*.txt >> "${REPORT_DIR}/${REPORT_FILE}" 175 | 176 | - name: Upload collected report 177 | uses: actions/upload-artifact@v3 178 | with: 179 | name: disk-space-report-markdown 180 | path: ${{ env.REPORT_DIR }}/${{ env.REPORT_FILE }} 181 | 182 | - name: Checkout report branch 183 | uses: actions/checkout@v4 184 | with: 185 | ref: test-report 186 | 187 | - name: Overwrite old report 188 | run: | 189 | cp README.md.template README.md 190 | cat ${{ env.REPORT_DIR }}/${{ env.REPORT_FILE }} >> README.md 191 | 192 | cat "${REPORT_DIR}/${REPORT_FILE}" 193 | 194 | git config user.name github-actions 195 | git config user.email github-actions@github.com 196 | git add README.md 197 | git commit -m "Generated new report" && git push || echo "Report unchanged, not updating." 198 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'Maximize build disk space' 2 | description: 'Maximize the available disk space for your build job' 3 | branding: 4 | icon: 'crop' 5 | color: 'orange' 6 | inputs: 7 | root-reserve-mb: 8 | description: 'Space to be left free on the root filesystem, in Megabytes.' 9 | required: false 10 | default: '1024' 11 | temp-reserve-mb: 12 | description: 'Space to be left free on the temp filesystem (/mnt), in Megabytes.' 13 | required: false 14 | default: '100' 15 | swap-size-mb: 16 | description: 'Swap space to create, in Megabytes.' 17 | required: false 18 | default: '4096' 19 | overprovision-lvm: 20 | description: | 21 | Create the LVM disk images as sparse files, making the space required for the LVM image files *appear* unused on the 22 | hosting volumes until actually allocated. Use with care, this can lead to surprising out-of-disk-space situations. 23 | You should prefer adjusting root-reserve-mb/temp-reserve-mb over using this option. 24 | required: false 25 | default: 'false' 26 | build-mount-path: 27 | description: 'Absolute path to the mount point where the build space will be available, defaults to $GITHUB_WORKSPACE if unset.' 28 | required: false 29 | build-mount-path-ownership: 30 | description: 'Ownership of the mount point path, defaults to standard "runner" user and group.' 31 | required: false 32 | default: 'runner:runner' 33 | pv-loop-path: 34 | description: 'Absolute file path for the LVM image created on the root filesystem, the default is usually fine.' 35 | required: false 36 | default: '/pv.img' 37 | tmp-pv-loop-path: 38 | description: 'Absolute file path for the LVM image created on the temp filesystem, the default is usually fine. Must reside on /mnt' 39 | required: false 40 | default: '/mnt/tmp-pv.img' 41 | remove-dotnet: 42 | description: 'Removes .NET runtime and libraries. (frees ~17 GB)' 43 | required: false 44 | default: 'false' 45 | remove-android: 46 | description: 'Removes Android SDKs and Tools. (frees ~11 GB)' 47 | required: false 48 | default: 'false' 49 | remove-haskell: 50 | description: 'Removes GHC (Haskell) artifacts. (frees ~2.7 GB)' 51 | required: false 52 | default: 'false' 53 | remove-codeql: 54 | description: 'Removes CodeQL Action Bundles. (frees ~5.4 GB)' 55 | required: false 56 | default: 'false' 57 | remove-docker-images: 58 | description: 'Removes cached Docker images. (frees ~3 GB)' 59 | required: false 60 | default: 'false' 61 | runs: 62 | using: "composite" 63 | steps: 64 | - name: Disk space report before modification 65 | shell: bash 66 | run: | 67 | echo "Memory and swap:" 68 | sudo free -h 69 | echo 70 | sudo swapon --show 71 | echo 72 | 73 | echo "Available storage:" 74 | sudo df -h 75 | echo 76 | 77 | - name: Maximize build disk space 78 | shell: bash 79 | run: | 80 | set -euo pipefail 81 | 82 | BUILD_MOUNT_PATH="${{ inputs.build-mount-path }}" 83 | if [[ -z "${BUILD_MOUNT_PATH}" ]]; then 84 | BUILD_MOUNT_PATH="${GITHUB_WORKSPACE}" 85 | fi 86 | 87 | echo "Arguments:" 88 | echo 89 | echo " Root reserve: ${{ inputs.root-reserve-mb }} MiB" 90 | echo " Temp reserve: ${{ inputs.temp-reserve-mb }} MiB" 91 | echo " Swap space: ${{ inputs.swap-size-mb }} MiB" 92 | echo " Overprovision LVM: ${{ inputs.overprovision-lvm }}" 93 | echo " Mount path: ${BUILD_MOUNT_PATH}" 94 | echo " Root PV loop path: ${{ inputs.pv-loop-path }}" 95 | echo " Temp PV loop path: ${{ inputs.tmp-pv-loop-path }}" 96 | echo -n " Removing: " 97 | if [[ ${{ inputs.remove-dotnet }} == 'true' ]]; then 98 | echo -n "dotnet " 99 | fi 100 | if [[ ${{ inputs.remove-android }} == 'true' ]]; then 101 | echo -n "android " 102 | fi 103 | if [[ ${{ inputs.remove-haskell }} == 'true' ]]; then 104 | echo -n "haskell " 105 | fi 106 | if [[ ${{ inputs.remove-codeql }} == 'true' ]]; then 107 | echo -n "codeql " 108 | fi 109 | if [[ ${{ inputs.remove-docker-images }} == 'true' ]]; then 110 | echo -n "docker " 111 | fi 112 | echo 113 | 114 | # store owner of $GITHUB_WORKSPACE in case the action deletes it 115 | WORKSPACE_OWNER="$(stat -c '%U:%G' "${GITHUB_WORKSPACE}")" 116 | 117 | # ensure mount path exists before the action 118 | sudo mkdir -p "${BUILD_MOUNT_PATH}" 119 | sudo find "${BUILD_MOUNT_PATH}" -maxdepth 0 ! -empty -exec echo 'WARNING: directory [{}] is not empty, data loss might occur. Content:' \; -exec ls -al "{}" \; 120 | 121 | echo "Removing unwanted software... " 122 | if [[ ${{ inputs.remove-dotnet }} == 'true' ]]; then 123 | sudo rm -rf /usr/share/dotnet 124 | fi 125 | if [[ ${{ inputs.remove-android }} == 'true' ]]; then 126 | sudo rm -rf /usr/local/lib/android 127 | fi 128 | if [[ ${{ inputs.remove-haskell }} == 'true' ]]; then 129 | sudo rm -rf /opt/ghc 130 | fi 131 | if [[ ${{ inputs.remove-codeql }} == 'true' ]]; then 132 | sudo rm -rf /opt/hostedtoolcache/CodeQL 133 | fi 134 | if [[ ${{ inputs.remove-docker-images }} == 'true' ]]; then 135 | sudo docker image prune --all --force 136 | fi 137 | echo "... done" 138 | 139 | VG_NAME=buildvg 140 | 141 | # github runners have an active swap file in /mnt/swapfile 142 | # we want to reuse the temp disk, so first unmount swap and clean the temp disk 143 | echo "Unmounting and removing swap file." 144 | sudo swapoff -a 145 | sudo rm -f /mnt/swapfile 146 | 147 | echo "Creating LVM Volume." 148 | echo " Creating LVM PV on root fs." 149 | # create loop pv image on root fs 150 | ROOT_RESERVE_KB=$(expr ${{ inputs.root-reserve-mb }} \* 1024) 151 | ROOT_FREE_KB=$(df --block-size=1024 --output=avail / | tail -1) 152 | ROOT_LVM_SIZE_KB=$(expr $ROOT_FREE_KB - $ROOT_RESERVE_KB) 153 | ROOT_LVM_SIZE_BYTES=$(expr $ROOT_LVM_SIZE_KB \* 1024) 154 | sudo touch "${{ inputs.pv-loop-path }}" && sudo fallocate -z -l "${ROOT_LVM_SIZE_BYTES}" "${{ inputs.pv-loop-path }}" 155 | export ROOT_LOOP_DEV=$(sudo losetup --find --show "${{ inputs.pv-loop-path }}") 156 | sudo pvcreate -f "${ROOT_LOOP_DEV}" 157 | 158 | # create pv on temp disk 159 | echo " Creating LVM PV on temp fs." 160 | TMP_RESERVE_KB=$(expr ${{ inputs.temp-reserve-mb }} \* 1024) 161 | TMP_FREE_KB=$(df --block-size=1024 --output=avail /mnt | tail -1) 162 | TMP_LVM_SIZE_KB=$(expr $TMP_FREE_KB - $TMP_RESERVE_KB) 163 | TMP_LVM_SIZE_BYTES=$(expr $TMP_LVM_SIZE_KB \* 1024) 164 | sudo touch "${{ inputs.tmp-pv-loop-path }}" && sudo fallocate -z -l "${TMP_LVM_SIZE_BYTES}" "${{ inputs.tmp-pv-loop-path }}" 165 | export TMP_LOOP_DEV=$(sudo losetup --find --show "${{ inputs.tmp-pv-loop-path }}") 166 | sudo pvcreate -f "${TMP_LOOP_DEV}" 167 | 168 | # create volume group from these pvs 169 | sudo vgcreate "${VG_NAME}" "${TMP_LOOP_DEV}" "${ROOT_LOOP_DEV}" 170 | 171 | echo "Recreating swap" 172 | # create and activate swap 173 | sudo lvcreate -L "${{ inputs.swap-size-mb }}M" -n swap "${VG_NAME}" 174 | sudo mkswap "/dev/mapper/${VG_NAME}-swap" 175 | sudo swapon "/dev/mapper/${VG_NAME}-swap" 176 | 177 | echo "Creating build volume" 178 | # create and mount build volume 179 | sudo lvcreate -l 100%FREE -n buildlv "${VG_NAME}" 180 | if [[ ${{ inputs.overprovision-lvm }} == 'true' ]]; then 181 | sudo mkfs.ext4 -m0 "/dev/mapper/${VG_NAME}-buildlv" 182 | else 183 | sudo mkfs.ext4 -Enodiscard -m0 "/dev/mapper/${VG_NAME}-buildlv" 184 | fi 185 | sudo mount "/dev/mapper/${VG_NAME}-buildlv" "${BUILD_MOUNT_PATH}" 186 | sudo chown -R "${{ inputs.build-mount-path-ownership }}" "${BUILD_MOUNT_PATH}" 187 | 188 | # if build mount path is a parent of $GITHUB_WORKSPACE, and has been deleted, recreate it 189 | if [[ ! -d "${GITHUB_WORKSPACE}" ]]; then 190 | sudo mkdir -p "${GITHUB_WORKSPACE}" 191 | sudo chown -R "${WORKSPACE_OWNER}" "${GITHUB_WORKSPACE}" 192 | fi 193 | 194 | - name: Disk space report after modification 195 | shell: bash 196 | run: | 197 | echo "Memory and swap:" 198 | sudo free -h 199 | echo 200 | sudo swapon --show 201 | echo 202 | 203 | echo "Available storage:" 204 | sudo df -h 205 | --------------------------------------------------------------------------------