├── patches ├── last_processed_tag.txt └── last_processed_commit.txt ├── scripts ├── assets │ ├── 99synaptics │ ├── rc.local │ ├── 01-nodoc │ ├── gha-runner.service │ └── lxd-preseed.yaml ├── helpers │ ├── register-runner.sh │ ├── run_script.sh │ ├── setup_img.sh │ └── release-check.sh ├── vm.sh ├── docker.sh └── podman.sh ├── .gitignore ├── images ├── centos │ ├── assets │ │ └── post-gen │ │ │ ├── systemd-linger.sh │ │ │ ├── environment-variables.sh │ │ │ └── cleanup-logs.sh │ └── scripts │ │ ├── build │ │ ├── install-podman.sh │ │ ├── install-dnf-vital.sh │ │ ├── install-dnf-common.sh │ │ ├── install-git-lfs.sh │ │ ├── configure-limits.sh │ │ ├── install-pipx-packages.sh │ │ ├── install-git.sh │ │ ├── install-runner-package.sh │ │ ├── configure-dnfpkg.sh │ │ ├── configure-system.sh │ │ ├── cleanup.sh │ │ ├── install-actions-cache.sh │ │ ├── configure-dnf.sh │ │ ├── install-python.sh │ │ ├── configure-snap.sh │ │ ├── install-github-cli.sh │ │ ├── configure-yum-mock.sh │ │ ├── install-homebrew.sh │ │ ├── install-zstd.sh │ │ ├── install-snap.sh │ │ ├── install-lxd.sh │ │ ├── configure-image-data.sh │ │ ├── configure-runner.sh │ │ ├── install-dotnetcore-sdk.sh │ │ ├── configure-environment.sh │ │ └── install-docker.sh │ │ └── helpers │ │ ├── os.sh │ │ └── etc-environment.sh └── ubuntu │ ├── assets │ └── post-gen │ │ ├── systemd-linger.sh │ │ ├── environment-variables.sh │ │ └── cleanup-logs.sh │ └── scripts │ ├── helpers │ ├── os.sh │ └── etc-environment.sh │ └── build │ ├── install-apt-vital.sh │ ├── install-nginx.sh │ ├── install-apache.sh │ ├── install-sbt.sh │ ├── install-gcc-compilers.sh │ ├── install-gfortran.sh │ ├── install-apt-common.sh │ ├── install-ms-repos.sh │ ├── install-git-lfs.sh │ ├── install-miniconda.sh │ ├── install-leiningen.sh │ ├── install-bazel.sh │ ├── configure-limits.sh │ ├── install-ninja.sh │ ├── install-pipx-packages.sh │ ├── install-mssql-tools.sh │ ├── install-azure-cli.sh │ ├── install-oc-cli.sh │ ├── install-azcopy.sh │ ├── install-nvm.sh │ ├── install-kotlin.sh │ ├── install-rust.sh │ ├── install-bicep.sh │ ├── install-azure-devops-cli.sh │ ├── install-mysql.sh │ ├── install-packer.sh │ ├── install-rlang.sh │ ├── configure-snap.sh │ ├── install-git.sh │ ├── install-selenium.sh │ ├── install-runner-package.sh │ ├── install-heroku.sh │ ├── install-terraform.sh │ ├── install-nodejs.sh │ ├── install-yq.sh │ ├── configure-apt-sources.sh │ ├── install-google-cloud-cli.sh │ ├── install-actions-cache.sh │ ├── install-oras-cli.sh │ ├── cleanup.sh │ ├── install-vcpkg.sh │ ├── install-mono.sh │ ├── install-pulumi.sh │ ├── install-postgresql.sh │ ├── configure-system.sh │ ├── install-sqlpackage.sh │ ├── install-github-cli.sh │ ├── install-aliyun-cli.sh │ ├── install-homebrew.sh │ ├── install-zstd.sh │ ├── install-cmake.sh │ ├── install-snap.sh │ ├── install-python.sh │ ├── install-lxd.sh │ ├── install-clang.sh │ ├── install-julia.sh │ ├── configure-apt-mock.sh │ ├── install-container-tools.sh │ ├── configure-image-data.sh │ ├── install-aws-tools.sh │ ├── configure-runner.sh │ ├── configure-dpkg.sh │ ├── install-haskell.sh │ ├── install-firefox.sh │ ├── install-microsoft-edge.sh │ ├── configure-apt.sh │ ├── install-ruby.sh │ ├── install-codeql-bundle.sh │ ├── install-swift.sh │ ├── install-dotnetcore-sdk.sh │ ├── install-kubernetes-tools.sh │ ├── install-php.sh │ ├── configure-environment.sh │ ├── install-google-chrome.sh │ └── install-pypy.sh ├── dockerfiles ├── Dockerfile.test ├── Dockerfile.centos.9 ├── Dockerfile.ubuntu.22.04 └── Dockerfile.ubuntu.24.04 ├── .github ├── ISSUE_TEMPLATE │ ├── feature-request.md │ └── bug_report.md └── workflows │ ├── shellcheck.yml │ ├── complete_lxd_build.yml │ ├── build_main.yml │ └── build_release.yml ├── DCO.txt ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── docs ├── LXD_IMAGE_Used_by_GitHub_Actions_Runner.md └── OCI_Image_Used_as_a_Self-Hosted_GitHub_Actions_Runner.md └── README.md /patches/last_processed_tag.txt: -------------------------------------------------------------------------------- 1 | v2.330.0 2 | -------------------------------------------------------------------------------- /scripts/assets/99synaptics: -------------------------------------------------------------------------------- 1 | APT::Install-Recommends "false"; 2 | -------------------------------------------------------------------------------- /patches/last_processed_commit.txt: -------------------------------------------------------------------------------- 1 | c96dcd472907e514274cdb4af281116adf7aad18 2 | -------------------------------------------------------------------------------- /scripts/assets/rc.local: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | setcap 'cap_net_raw+p' /usr/bin/ping 3 | getcap /usr/bin/ping 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | distro/ 2 | distro/*.tar.* 3 | distro/rootfs_almalinux_* 4 | distro/rootfs.squashfs 5 | distro/almalinux.yaml 6 | *.log 7 | -------------------------------------------------------------------------------- /images/centos/assets/post-gen/systemd-linger.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Enable user session on boot, not on login 4 | UserId=$(cut -d: -f3 /etc/passwd | tail -1) 5 | loginctl enable-linger "$UserId" 6 | -------------------------------------------------------------------------------- /images/ubuntu/assets/post-gen/systemd-linger.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Enable user session on boot, not on login 4 | UserId=$(cut -d: -f3 /etc/passwd | tail -1) 5 | loginctl enable-linger "$UserId" 6 | -------------------------------------------------------------------------------- /dockerfiles/Dockerfile.test: -------------------------------------------------------------------------------- 1 | FROM localhost/runner:almalinux 2 | 3 | ARG REPO TOKEN 4 | 5 | RUN /opt/runner-cache/config.sh --url ${REPO} --token ${TOKEN} 6 | 7 | CMD /opt/runner-cache/run.sh 8 | -------------------------------------------------------------------------------- /images/centos/assets/post-gen/environment-variables.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Replace $HOME with the default user's home directory for environmental variables related to the default user home directory 4 | 5 | homeDir=$(cut -d: -f6 /etc/passwd | tail -1) 6 | sed -i "s|\$HOME|$homeDir|g" /etc/environment -------------------------------------------------------------------------------- /images/ubuntu/assets/post-gen/environment-variables.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Replace $HOME with the default user's home directory for environmental variables related to the default user home directory 4 | 5 | homeDir=$(cut -d: -f6 /etc/passwd | tail -1) 6 | sed -i "s|\$HOME|$homeDir|g" /etc/environment -------------------------------------------------------------------------------- /images/centos/scripts/build/install-podman.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-snap.sh 4 | ## Desc: Install snapd 5 | ################################################################################ 6 | # shellcheck disable=SC1091 7 | source "$HELPER_SCRIPTS"/install.sh 8 | 9 | dnf -y install podman -------------------------------------------------------------------------------- /scripts/assets/01-nodoc: -------------------------------------------------------------------------------- 1 | path-exclude /usr/share/doc/* 2 | # we need to keep copyright files for legal reasons 3 | path-include /usr/share/doc/*/copyright 4 | path-exclude /usr/share/man/* 5 | path-exclude /usr/share/groff/* 6 | path-exclude /usr/share/info/* 7 | # lintian stuff is small, but really unnecessary 8 | path-exclude /usr/share/lintian/* 9 | path-exclude /usr/share/linda/* 10 | -------------------------------------------------------------------------------- /scripts/assets/gha-runner.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=GitHub Actions Runner 3 | After=network.target 4 | 5 | [Service] 6 | Environment=DOTNET_ROOT='/opt/dotnet' 7 | ExecStart=/usr/bin/bash -c "/opt/runner-cache/run.sh" 8 | User=ubuntu 9 | WorkingDirectory=/opt/runner-cache 10 | KillMode=process 11 | KillSignal=SIGTERM 12 | TimeoutStopSec=5min 13 | 14 | [Install] 15 | WantedBy=multi-user.target 16 | -------------------------------------------------------------------------------- /images/centos/assets/post-gen/cleanup-logs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # journalctl 4 | if command -v journalctl; then 5 | journalctl --rotate 6 | journalctl --vacuum-time=1s 7 | fi 8 | 9 | # delete all .gz and rotated file 10 | find /var/log -type f -regex ".*\.gz$" -delete 11 | find /var/log -type f -regex ".*\.[0-9]$" -delete 12 | 13 | # wipe log files 14 | find /var/log/ -type f -exec cp /dev/null {} \; -------------------------------------------------------------------------------- /images/ubuntu/assets/post-gen/cleanup-logs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # journalctl 4 | if command -v journalctl; then 5 | journalctl --rotate 6 | journalctl --vacuum-time=1s 7 | fi 8 | 9 | # delete all .gz and rotated file 10 | find /var/log -type f -regex ".*\.gz$" -delete 11 | find /var/log -type f -regex ".*\.[0-9]$" -delete 12 | 13 | # wipe log files 14 | find /var/log/ -type f -exec cp /dev/null {} \; -------------------------------------------------------------------------------- /images/centos/scripts/helpers/os.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: os.sh 4 | ## Desc: Helper functions for OS releases 5 | ################################################################################ 6 | is_centos9() { 7 | lsb_release -rs | grep '9' 8 | } 9 | 10 | is_centos10() { 11 | lsb_release -rs | grep '10' 12 | } 13 | 14 | 15 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/helpers/os.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: os.sh 4 | ## Desc: Helper functions for OS releases 5 | ################################################################################ 6 | 7 | is_ubuntu22() { 8 | lsb_release -rs | grep -q '22.04' 9 | } 10 | 11 | is_ubuntu24() { 12 | lsb_release -rs | grep -q '24.04' 13 | } 14 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-apt-vital.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-apt-vital.sh 4 | ## Desc: Install vital command line utilities 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | vital_packages=$(get_toolset_value .apt.vital_packages[]) 12 | install_dpkgs --no-install-recommends "$vital_packages" 13 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-nginx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-nginx.sh 4 | ## Desc: Install Nginx 5 | ################################################################################ 6 | 7 | # Install Nginx 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/os.sh 10 | source "$HELPER_SCRIPTS"/install.sh 11 | install_dpkgs nginx 12 | 13 | # Disable nginx.service 14 | systemctl is-active --quiet nginx.service && systemctl stop nginx.service 15 | systemctl disable nginx.service 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: feature request, needs triage 6 | assignees: '@mtarsel @anup-kodlekere @rahulssv-ibm @adilhusain-s' 7 | --- 8 | 9 | 10 | **Description:** 11 | Describe your proposal. 12 | 13 | **Justification:** 14 | Justification or a use case for your proposal. 15 | 16 | **Are you willing to submit a PR?** 17 | 18 | -------------------------------------------------------------------------------- /images/centos/scripts/build/install-dnf-vital.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-dnf-vital.sh 4 | ## Desc: Install vital command-line utilities 5 | ################################################################################ 6 | # Source the helpers for use with the script 7 | # shellcheck disable=SC1091 8 | source "$HELPER_SCRIPTS"/install.sh 9 | 10 | vital_packages=$(get_toolset_value .dnf.vital_packages[]) 11 | 12 | # Install vital packages using dnf 13 | install_dnfpkgs --setopt=install_weak_deps=False "$vital_packages" 14 | -------------------------------------------------------------------------------- /.github/workflows/shellcheck.yml: -------------------------------------------------------------------------------- 1 | name: ShellCheck Lint 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | paths: [ "**.sh" ] # Only run if shell files change 7 | pull_request: 8 | branches: [ "main" ] 9 | paths: [ "**.sh" ] 10 | workflow_dispatch: 11 | 12 | jobs: 13 | shellcheck: 14 | name: Run ShellCheck 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Checkout code 18 | uses: actions/checkout@v5 19 | 20 | - name: Run ShellCheck 21 | uses: ludeeus/action-shellcheck@master 22 | with: 23 | # Optional: check specific directory 24 | scandir: '.' -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-apache.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-apache.sh 4 | ## Desc: Install Apache HTTP Server 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | # Install Apache 12 | install_dpkgs apache2 13 | 14 | # Disable apache2.service 15 | systemctl is-active --quiet apache2.service && systemctl stop apache2.service 16 | systemctl disable apache2.service 17 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-sbt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-sbt.sh 4 | ## Desc: Install sbt 5 | ################################################################################ 6 | 7 | # shellcheck disable=SC1091 8 | source "$HELPER_SCRIPTS"/install.sh 9 | 10 | # Install latest sbt release 11 | download_url=$(resolve_github_release_asset_url "sbt/sbt" "endswith(\".tgz\")" "latest") 12 | archive_path=$(download_with_retry "$download_url") 13 | tar zxf "$archive_path" -C /usr/share 14 | ln -s /usr/share/sbt/bin/sbt /usr/bin/sbt 15 | 16 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-gcc-compilers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-gcc-compilers.sh 4 | ## Desc: Install GNU C++ compilers 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | versions=$(get_toolset_value '.gcc.versions[]') 12 | 13 | # shellcheck disable=SC2048 14 | for version in ${versions[*]}; do 15 | echo "Installing $version..." 16 | install_dpkgs "$version" 17 | done 18 | -------------------------------------------------------------------------------- /scripts/assets/lxd-preseed.yaml: -------------------------------------------------------------------------------- 1 | config: {} 2 | cluster: null 3 | networks: 4 | - config: 5 | bridge.mtu: "1460" 6 | ipv4.address: auto 7 | ipv6.address: auto 8 | description: "gaplib network" 9 | name: lxdbr0 10 | type: bridge 11 | project: default 12 | storage_pools: 13 | - config: {} 14 | description: "gaplib storage pool" 15 | name: default 16 | driver: dir 17 | profiles: 18 | - config: {} 19 | description: "gaplib" 20 | devices: 21 | eth0: 22 | name: eth0 23 | nictype: bridged 24 | parent: lxdbr0 25 | type: nic 26 | root: 27 | path: / 28 | pool: default 29 | type: disk 30 | name: default 31 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-gfortran.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-gfortran.sh 4 | ## Desc: Install GNU Fortran 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | versions=$(get_toolset_value '.gfortran.versions[]') 12 | 13 | # shellcheck disable=SC2048 14 | for version in ${versions[*]}; do 15 | echo "Installing $version..." 16 | install_dpkgs "$version" 17 | done 18 | 19 | echo "Install versionless gfortran (latest)" 20 | install_dpkgs gfortran 21 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-apt-common.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-apt-common.sh 4 | ## Desc: Install basic command line utilities and dev packages 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | common_packages=$(get_toolset_value .apt.common_packages[]) 12 | cmd_packages=$(get_toolset_value .apt.cmd_packages[]) 13 | 14 | for package in $common_packages $cmd_packages; do 15 | echo "Install $package" 16 | install_dpkgs --no-install-recommends "$package" 17 | done 18 | -------------------------------------------------------------------------------- /images/centos/scripts/build/install-dnf-common.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-dnf-common.sh 4 | ## Desc: Install basic command-line utilities and development packages 5 | ################################################################################ 6 | # Source the helpers for use with the script 7 | # shellcheck disable=SC1091 8 | source "$HELPER_SCRIPTS"/install.sh 9 | 10 | common_packages=$(get_toolset_value .dnf.common_packages[]) 11 | cmd_packages=$(get_toolset_value .dnf.cmd_packages[]) 12 | 13 | for package in $common_packages $cmd_packages; do 14 | echo "Install $package" 15 | install_dnfpkgs --setopt=install_weak_deps=False "$package" 16 | done -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-ms-repos.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-ms-repos.sh 4 | ## Desc: Install official Microsoft package repos for the distribution 5 | ################################################################################ 6 | 7 | os_label=$(lsb_release -rs) 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | # Install Microsoft repository 12 | wget https://packages.microsoft.com/config/ubuntu/"$os_label"/packages-microsoft-prod.deb 13 | dpkg -i packages-microsoft-prod.deb 14 | 15 | # update 16 | install_dpkgs apt-transport-https ca-certificates curl software-properties-common 17 | update_dpkgs 18 | apt-get dist-upgrade 19 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-git-lfs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-git-lfs.sh 4 | ## Desc: Install Git-lfs 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | GIT_LFS_REPO="https://packagecloud.io/install/repositories/github/git-lfs" 12 | 13 | # Install git-lfs 14 | curl -fsSL $GIT_LFS_REPO/script.deb.sh | bash 15 | install_dpkgs git-lfs 16 | 17 | # Remove source repo's 18 | rm /etc/apt/sources.list.d/github_git-lfs.list 19 | 20 | # Document apt source repo's 21 | echo "git-lfs $GIT_LFS_REPO" >> "$HELPER_SCRIPTS"/apt-sources.txt -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-miniconda.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-miniconda.sh 4 | ## Desc: Install miniconda 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/etc-environment.sh 10 | 11 | # Install Miniconda 12 | curl -fsSL https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-"${ARCH}".sh -o miniconda.sh \ 13 | && chmod +x miniconda.sh \ 14 | && ./miniconda.sh -b -p /usr/share/miniconda \ 15 | && rm miniconda.sh 16 | 17 | CONDA=/usr/share/miniconda 18 | set_etc_environment_variable "CONDA" "${CONDA}" 19 | 20 | ln -s $CONDA/bin/conda /usr/bin/conda -------------------------------------------------------------------------------- /images/centos/scripts/build/install-git-lfs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-git-lfs.sh 4 | ## Desc: Install Git-lfs 5 | ################################################################################ 6 | # Load helper functions (if any) 7 | # shellcheck disable=SC1091 8 | source "$HELPER_SCRIPTS"/install.sh 9 | 10 | GIT_LFS_REPO="https://packagecloud.io/github/git-lfs/el/9" 11 | 12 | # Install git-lfs 13 | curl -fsSL https://packagecloud.io/install/repositories/github/git-lfs/script.rpm.sh | sudo bash 14 | install_dnfpkgs git-lfs 15 | 16 | # Remove source repo's 17 | sudo rm -f /etc/yum.repos.d/github_git-lfs.repo 18 | 19 | # Document installed Git LFS repo 20 | echo "git-lfs $GIT_LFS_REPO" | sudo tee -a "$HELPER_SCRIPTS"/package-versions.txt 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a bug report 4 | title: '' 5 | labels: bug, needs triage 6 | assignees: '@gha-sre' 7 | 8 | --- 9 | 10 | 11 | 12 | **Description:** 13 | A clear and concise description of what the bug is. 14 | 15 | **Action version:** 16 | Specify the action version or git commit used in development. 17 | 18 | **Platform:** 19 | - [ ] ppc64le 20 | - [ ] s390x 21 | 22 | 23 | **Steps to Reproduce** 24 | A description with steps to reproduce the issue. If your have a public example or repo to share, please provide the link. 25 | 26 | **Expected behavior:** 27 | A description of what you expected to happen. 28 | 29 | **Actual behavior:** 30 | A description of what is actually happening. 31 | -------------------------------------------------------------------------------- /scripts/helpers/register-runner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while getopts r:t:l:n flag 4 | do 5 | # shellcheck disable=SC2220 6 | case "${flag}" in 7 | r) repo=${OPTARG};; 8 | t) token=${OPTARG};; 9 | l) label=${OPTARG};; 10 | n) name=${OPTARG};; 11 | esac 12 | done 13 | 14 | # shellcheck disable=SC1035 15 | while !(ping -q -c 1 -W 1 google.com >/dev/null) 16 | do 17 | echo "waiting for internet connectivity..." 18 | sleep 2 19 | done 20 | 21 | cd /opt/runner-cache || exit 22 | 23 | # register the runner 24 | export DOTNET_ROOT=/opt/dotnet 25 | export PATH=$PATH:$DOTNET_ROOT 26 | ./config.sh \ 27 | --unattended \ 28 | --disableupdate \ 29 | --ephemeral \ 30 | --name "${name}" \ 31 | --labels "${label}" \ 32 | --url "https://github.com/${repo}" \ 33 | --token "${token}" 34 | 35 | /usr/bin/bash -l -c "./run.sh" 36 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-leiningen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-leiningen.sh 4 | ## Desc: Install Leiningen 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/etc-environment.sh 10 | 11 | LEIN_BIN=/usr/local/bin/lein 12 | curl -fsSL https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein > $LEIN_BIN 13 | chmod 0755 $LEIN_BIN 14 | 15 | # Run lein to trigger self-install 16 | export LEIN_HOME=/usr/local/lib/lein 17 | lein 18 | 19 | LEIN_JAR=$(find $LEIN_HOME -name "leiningen-*-standalone.jar") 20 | set_etc_environment_variable "LEIN_JAR" "${LEIN_JAR}" 21 | set_etc_environment_variable "LEIN_HOME" "${LEIN_HOME}" 22 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-bazel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-bazel.sh 4 | ## Desc: Install Bazel and Bazelisk (A user-friendly launcher for Bazel) 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | # Set architecture-specific variables using a case statement for clarity 12 | case "$ARCH" in 13 | "ppc64le" | "s390x") 14 | echo "No actions defined for $ARCH architecture." 15 | exit 0 16 | ;; 17 | *) 18 | ;; 19 | esac 20 | 21 | # Install bazelisk 22 | npm install -g @bazel/bazelisk 23 | 24 | # run bazelisk once in order to install /usr/local/bin/bazel binary 25 | sudo -u "$SUDO_USER" bazel version 26 | 27 | -------------------------------------------------------------------------------- /images/centos/scripts/build/configure-limits.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: configure-limits.sh 4 | ## Desc: Configure limits 5 | ################################################################################ 6 | echo 'session required pam_limits.so' >> /etc/pam.d/common-session 7 | echo 'session required pam_limits.so' >> /etc/pam.d/common-session-noninteractive 8 | echo 'DefaultLimitNOFILE=65536' >> /etc/systemd/system.conf 9 | echo 'DefaultLimitSTACK=16M:infinity' >> /etc/systemd/system.conf 10 | 11 | # Raise Number of File Descriptors 12 | # shellcheck disable=SC2129 13 | echo '* soft nofile 65536' >> /etc/security/limits.conf 14 | echo '* hard nofile 65536' >> /etc/security/limits.conf 15 | 16 | # Double stack size from default 8192KB 17 | echo '* soft stack 16384' >> /etc/security/limits.conf 18 | echo '* hard stack 16384' >> /etc/security/limits.conf 19 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/configure-limits.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: configure-limits.sh 4 | ## Desc: Configure limits 5 | ################################################################################ 6 | 7 | echo 'session required pam_limits.so' >> /etc/pam.d/common-session 8 | echo 'session required pam_limits.so' >> /etc/pam.d/common-session-noninteractive 9 | echo 'DefaultLimitNOFILE=65536' >> /etc/systemd/system.conf 10 | echo 'DefaultLimitSTACK=16M:infinity' >> /etc/systemd/system.conf 11 | 12 | # Raise Number of File Descriptors 13 | # shellcheck disable=SC2129 14 | echo '* soft nofile 65536' >> /etc/security/limits.conf 15 | echo '* hard nofile 65536' >> /etc/security/limits.conf 16 | 17 | # Double stack size from default 8192KB 18 | echo '* soft stack 16384' >> /etc/security/limits.conf 19 | echo '* hard stack 16384' >> /etc/security/limits.conf 20 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-ninja.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-ninja.sh 4 | ## Desc: Install ninja-build 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | # Set architecture-specific variables using a case statement for clarity 12 | case "$ARCH" in 13 | "ppc64le" | "s390x") 14 | install_dpkgs ninja-build 15 | exit 0 16 | ;; 17 | *) 18 | ;; 19 | esac 20 | 21 | # Install ninja 22 | download_url=$(resolve_github_release_asset_url "ninja-build/ninja" "endswith(\"ninja-linux.zip\")" "latest") 23 | ninja_binary_path=$(download_with_retry "${download_url}") 24 | 25 | # Unzip the ninja binary 26 | unzip -qq "$ninja_binary_path" -d /usr/local/bin 27 | 28 | -------------------------------------------------------------------------------- /images/centos/scripts/build/install-pipx-packages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-pipx-packages.sh 4 | ## Desc: Install tools via pipx 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | export PATH="$PATH:/opt/pipx_bin" 12 | 13 | pipx_packages=$(get_toolset_value ".pipx[] .package") 14 | 15 | for package in $pipx_packages; do 16 | echo "Install $package into default python" 17 | pipx install "$package" 18 | 19 | # https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html 20 | # Install ansible into an existing ansible-core Virtual Environment 21 | if [[ $package == "ansible-core" ]]; then 22 | pipx inject "$package" ansible 23 | fi 24 | done 25 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-pipx-packages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-pipx-packages.sh 4 | ## Desc: Install tools via pipx 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | export PATH="$PATH:/opt/pipx_bin" 12 | 13 | pipx_packages=$(get_toolset_value ".pipx[] .package") 14 | 15 | for package in $pipx_packages; do 16 | echo "Install $package into default python" 17 | pipx install "$package" 18 | 19 | # https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html 20 | # Install ansible into an existing ansible-core Virtual Environment 21 | if [[ $package == "ansible-core" ]]; then 22 | pipx inject "$package" ansible 23 | fi 24 | done 25 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-mssql-tools.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-mssql-tools.sh 4 | ## Desc: Install MS SQL Server client tools (https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-setup-tools?view=sql-server-2017) 5 | ################################################################################ 6 | # Source the helpers for use with the script 7 | # shellcheck disable=SC1091 8 | source "$HELPER_SCRIPTS"/install.sh 9 | 10 | # Set architecture-specific variables using a case statement for clarity 11 | case "$ARCH" in 12 | "ppc64le" | "s390x") 13 | echo "No actions defined for $ARCH architecture." 14 | exit 0 15 | ;; 16 | *) 17 | ;; 18 | esac 19 | 20 | export ACCEPT_EULA=Y 21 | 22 | update_dpkgs 23 | install_dpkgs mssql-tools unixodbc-dev 24 | apt-get -f install 25 | ln -s /opt/mssql-tools/bin/* /usr/local/bin/ 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-azure-cli.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-azure-cli.sh 4 | ## Desc: Install Azure CLI (az) 5 | ################################################################################ 6 | 7 | # Set architecture-specific variables using a case statement for clarity 8 | case "$ARCH" in 9 | "ppc64le" | "s390x") 10 | echo "No actions defined for $ARCH architecture." 11 | exit 0 12 | ;; 13 | *) 14 | ;; 15 | esac 16 | 17 | # Install Azure CLI (instructions taken from https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) 18 | curl -fsSL https://aka.ms/InstallAzureCLIDeb | sudo bash 19 | 20 | echo "azure-cli https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-linux?pivots=apt" >> "$HELPER_SCRIPTS"/apt-sources.txt 21 | 22 | rm -f /etc/apt/sources.list.d/azure-cli.list 23 | rm -f /etc/apt/sources.list.d/azure-cli.list.save 24 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-oc-cli.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-oc-cli.sh 4 | ## Desc: Install the OC CLI 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/os.sh 10 | source "$HELPER_SCRIPTS"/install.sh 11 | 12 | # Set architecture-specific variables using a case statement for clarity 13 | case "$ARCH" in 14 | "x86_64") 15 | package_arch="amd64" 16 | ;; 17 | "ppc64le" | "s390x" | *) 18 | package_arch="$ARCH" 19 | ;; 20 | esac 21 | 22 | # Install the oc CLI 23 | download_url="https://mirror.openshift.com/pub/openshift-v4/${package_arch}/clients/ocp/latest/openshift-client-linux.tar.gz" 24 | 25 | archive_path=$(download_with_retry "$download_url") 26 | 27 | tar xzf "$archive_path" -C "/usr/local/bin" oc 28 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-azcopy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-azcopy.sh 4 | ## Desc: Install AzCopy 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | # Set architecture-specific variables using a case statement for clarity 12 | case "$ARCH" in 13 | "ppc64le" | "s390x") 14 | echo "No actions defined for $ARCH architecture." 15 | exit 0 16 | ;; 17 | *) 18 | ;; 19 | esac 20 | 21 | # Install AzCopy10 22 | archive_path=$(download_with_retry "https://aka.ms/downloadazcopy-v10-linux") 23 | tar xzf "$archive_path" --strip-components=1 -C /tmp 24 | install /tmp/azcopy /usr/local/bin/azcopy 25 | 26 | # Create azcopy 10 alias for backward compatibility 27 | ln -sf /usr/local/bin/azcopy /usr/local/bin/azcopy10 28 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-nvm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-nvm.sh 4 | ## Desc: Install Nvm 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/etc-environment.sh 10 | 11 | export NVM_DIR="/etc/skel/.nvm" 12 | mkdir "$NVM_DIR" 13 | nvm_version=$(curl -fsSL https://api.github.com/repos/nvm-sh/nvm/releases/latest | jq -r '.tag_name') 14 | curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/"$nvm_version"/install.sh | bash 15 | # shellcheck disable=SC2016 16 | set_etc_environment_variable "NVM_DIR" '$HOME/.nvm' 17 | 18 | # shellcheck disable=SC2016 19 | echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm' | tee -a /etc/skel/.bash_profile 20 | [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" 21 | 22 | # set system node.js as default one 23 | nvm alias default system 24 | -------------------------------------------------------------------------------- /images/centos/scripts/build/install-git.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-git.sh 4 | ## Desc: Install Git and Git-FTP 5 | ################################################################################ 6 | # Load helper functions (if any) 7 | # shellcheck disable=SC1091 8 | source "$HELPER_SCRIPTS"/install.sh 9 | 10 | # Enable EPEL repository for additional packages 11 | install_dnfpkgs epel-release 12 | 13 | # Install Git 14 | install_dnfpkgs git 15 | 16 | # Git version 2.35.2 introduces a security fix that breaks action/checkout 17 | cat < /usr/share/keyrings/rlang.gpg 24 | echo "deb [signed-by=/usr/share/keyrings/rlang.gpg] https://cloud.r-project.org/bin/linux/ubuntu $os_label-cran40/" > /etc/apt/sources.list.d/rlang.list 25 | 26 | update_dpkgs 27 | install_dpkgs r-base 28 | 29 | rm /etc/apt/sources.list.d/rlang.list 30 | rm /usr/share/keyrings/rlang.gpg 31 | 32 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/configure-snap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: configure-snap.sh 4 | ## Desc: Configure snap 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/etc-environment.sh 10 | 11 | # Update /etc/environment to include /snap/bin in PATH 12 | # because /etc/profile.d is ignored by `--norc` shell launch option 13 | 14 | prepend_etc_environment_path "/snap/bin" 15 | 16 | # Put snapd auto refresh on hold 17 | # as it may generate too much traffic on Canonical's snap server 18 | # when they are rolling a new major update out. 19 | # Hold is calculated as today's date + 60 days 20 | 21 | # snapd is started automatically, but during image generation 22 | # a unix socket may die, restart snapd.service (and therefore snapd.socket) 23 | # to make sure the socket is alive. 24 | 25 | systemctl restart snapd.socket 26 | systemctl restart snapd 27 | snap set system refresh.hold="$(date --date='today+60 days' +%Y-%m-%dT%H:%M:%S%:z)" 28 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-git.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-git.sh 4 | ## Desc: Install Git and Git-FTP 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | GIT_REPO="ppa:git-core/ppa" 12 | 13 | ## Install git 14 | add-apt-repository $GIT_REPO -y 15 | update_dpkgs 16 | install_dpkgs git 17 | 18 | # Git version 2.35.2 introduces security fix that breaks action\checkout https://github.com/actions/checkout/issues/760 19 | cat <> /etc/gitconfig 20 | [safe] 21 | directory = * 22 | EOF 23 | 24 | # Install git-ftp 25 | install_dpkgs git-ftp 26 | 27 | # Remove source repo's 28 | add-apt-repository --remove -y $GIT_REPO 29 | 30 | # Document apt source repo's 31 | echo "git-core $GIT_REPO" >> "$HELPER_SCRIPTS"/apt-sources.txt 32 | 33 | # Add well-known SSH host keys to known_hosts 34 | ssh-keyscan -t rsa,ecdsa,ed25519 github.com >> /etc/ssh/ssh_known_hosts 35 | ssh-keyscan -t rsa ssh.dev.azure.com >> /etc/ssh/ssh_known_hosts -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-selenium.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-selenium.sh 4 | ## Desc: Install selenium server 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | source "$HELPER_SCRIPTS"/etc-environment.sh 11 | 12 | selenium_major_version=$(get_toolset_value '.selenium.version') 13 | 14 | # Download Selenium server 15 | selenium_download_url=$(resolve_github_release_asset_url "SeleniumHQ/selenium" "contains(\"selenium-server-\") and endswith(\".jar\")" "$selenium_major_version\.+" "" "true") 16 | selenium_jar_path=$(download_with_retry "$selenium_download_url" "/usr/share/java/selenium-server.jar") 17 | 18 | # Create an empty file to retrieve selenium version 19 | selenium_full_version=$(echo "$selenium_download_url" | awk -F"selenium-server-|.jar" '{print $2}') 20 | touch "/usr/share/java/selenium-server-$selenium_full_version" 21 | 22 | # Add SELENIUM_JAR_PATH environment variable 23 | set_etc_environment_variable "SELENIUM_JAR_PATH" "$selenium_jar_path" 24 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-runner-package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-runner-package.sh 4 | ## Desc: Download and Install runner package 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | SRC=$(readlink -f "${BASH_SOURCE[0]}") 12 | DIR=$(dirname "${SRC}") 13 | 14 | # Set architecture-specific variables using a case statement for clarity 15 | case "$ARCH" in 16 | "ppc64le" | "s390x") 17 | source "${DIR}/configure-runner.sh" 18 | exit 0 19 | ;; 20 | "x86_64") 21 | package_arch="x64" 22 | ;; 23 | *) 24 | package_arch="$ARCH" 25 | ;; 26 | esac 27 | 28 | download_url=$(resolve_github_release_asset_url "actions/runner" "test(\"actions-runner-linux-${package_arch}-[0-9]+\\\\.[0-9]{3}\\\\.[0-9]+\\\\.tar\\\\.gz$\")" "latest") 29 | archive_name="${download_url##*/}" 30 | archive_path=$(download_with_retry "$download_url") 31 | 32 | mkdir -p /opt/runner-cache 33 | mv "$archive_path" "/opt/runner-cache/$archive_name" -------------------------------------------------------------------------------- /images/centos/scripts/build/install-runner-package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-runner-package.sh 4 | ## Desc: Download and Install runner package 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | SRC=$(readlink -f "${BASH_SOURCE[0]}") 12 | DIR=$(dirname "${SRC}") 13 | 14 | # Set architecture-specific variables using a case statement for clarity 15 | case "$ARCH" in 16 | "ppc64le" | "s390x") 17 | source "${DIR}/configure-runner.sh" 18 | exit 0 19 | ;; 20 | "x86_64") 21 | package_arch="x64" 22 | ;; 23 | *) 24 | package_arch="$ARCH" 25 | ;; 26 | esac 27 | 28 | download_url=$(resolve_github_release_asset_url "actions/runner" "test(\"actions-runner-linux-${package_arch}-[0-9]+\\\\.[0-9]{3}\\\\.[0-9]+\\\\.tar\\\\.gz$\")" "latest") 29 | archive_name="${download_url##*/}" 30 | archive_path=$(download_with_retry "$download_url") 31 | 32 | mkdir -p /opt/runner-cache 33 | mv "$archive_path" "/opt/runner-cache/$archive_name" 34 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-heroku.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-heroku.sh 4 | ## Desc: Install Heroku CLI. Based on instructions found here: https://devcenter.heroku.com/articles/heroku-cli 5 | ################################################################################ 6 | # Source the helpers for use with the script 7 | # shellcheck disable=SC1091 8 | source "$HELPER_SCRIPTS"/install.sh 9 | 10 | # Set architecture-specific variables using a case statement for clarity 11 | case "$ARCH" in 12 | "ppc64le" | "s390x") 13 | echo "No actions defined for $ARCH architecture." 14 | exit 0 15 | ;; 16 | *) 17 | ;; 18 | esac 19 | 20 | REPO_URL="https://cli-assets.heroku.com/channels/stable/apt" 21 | GPG_KEY="/usr/share/keyrings/heroku.gpg" 22 | REPO_PATH="/etc/apt/sources.list.d/heroku.list" 23 | 24 | # add heroku repository to apt 25 | curl -fsSL "${REPO_URL}/release.key" | gpg --dearmor -o $GPG_KEY 26 | echo "deb [trusted=yes] $REPO_URL ./" > $REPO_PATH 27 | 28 | # install heroku 29 | update_dpkgs 30 | install_dpkgs heroku 31 | 32 | # remove heroku's apt repository 33 | rm $REPO_PATH 34 | rm $GPG_KEY 35 | 36 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-terraform.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-terraform.sh 4 | ## Desc: Install terraform 5 | ################################################################################ 6 | 7 | # shellcheck disable=SC1091 8 | source "$HELPER_SCRIPTS"/install.sh 9 | 10 | # Set architecture-specific variables using a case statement for clarity 11 | case "$ARCH" in 12 | "ppc64le") 13 | wget -O /usr/local/bin/terraform https://ftp2.osuosl.org/pub/ppc64el/terraform/terraform-1.4.6 14 | chmod +x /usr/local/bin/terraform 15 | exit 0 16 | ;; 17 | "s390x") 18 | echo "No actions defined for $ARCH architecture." 19 | exit 0 20 | ;; 21 | "x86_64") 22 | package_arch="amd64" 23 | ;; 24 | *) 25 | package_arch="$ARCH" 26 | ;; 27 | esac 28 | 29 | # Install Terraform 30 | download_url=$(curl -fsSL https://api.releases.hashicorp.com/v1/releases/terraform/latest | jq -r --arg arch "$package_arch" '.builds[] | select((.arch==$arch) and (.os=="linux")).url') 31 | archive_path=$(download_with_retry "${download_url}") 32 | unzip -qq "$archive_path" -d /usr/local/bin 33 | 34 | 35 | -------------------------------------------------------------------------------- /images/centos/scripts/build/configure-dnfpkg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: configure-dnfpkg.sh 4 | ## Desc: Configure dnf and package management settings 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/etc-environment.sh 10 | 11 | # Configure dnf to automatically answer 'yes' for package installation 12 | # This replaces the non-interactive mode typically set in DEBIAN_FRONTEND 13 | # shellcheck disable=SC2129 14 | echo "assumeyes=True" >> /etc/dnf/dnf.conf 15 | 16 | # Prevent dnf from prompting for confirmation on replacing configuration files 17 | # Equivalent to dpkg's --force-confdef --force-confold 18 | echo "override_install_langs=en_US.UTF-8" >> /etc/dnf/dnf.conf 19 | 20 | # Hide information about packages that are no longer required 21 | # dnf has an autoremove feature, but it can be configured to prevent auto removal prompts 22 | echo "clean_requirements_on_remove=True" >> /etc/dnf/dnf.conf 23 | 24 | # Configure dnf to automatically clean up unused packages and dependencies 25 | echo "autoclean_metadata=True" >> /etc/dnf/dnf.conf 26 | -------------------------------------------------------------------------------- /images/centos/scripts/build/configure-system.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: configure-system.sh 4 | ## Desc: Post deployment system configuration actions for CentOS 5 | ################################################################################ 6 | 7 | # Source helper scripts 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/etc-environment.sh 10 | source "$HELPER_SCRIPTS"/os.sh 11 | 12 | # Move post-generation files to /opt 13 | mv -f "${IMAGE_FOLDER}/post-generation" /opt 14 | 15 | # Adjust permissions 16 | echo "chmod -R 777 /opt" 17 | chmod -R 777 /opt 18 | echo "chmod -R 777 /usr/share" 19 | chmod -R 777 /usr/share 20 | 21 | chmod 755 "$IMAGE_FOLDER" 22 | 23 | # Remove quotes around PATH in /etc/environment 24 | ENVPATH=$(grep 'PATH=' /etc/environment | head -n 1 | sed -z 's/^PATH=*//') 25 | ENVPATH=${ENVPATH#"\""} 26 | ENVPATH=${ENVPATH%"\""} 27 | replace_etc_environment_variable "PATH" "${ENVPATH}" 28 | echo "Updated /etc/environment: $(cat /etc/environment)" 29 | 30 | # Clean yarn and npm cache if installed 31 | if command -v yarn > /dev/null; then 32 | yarn cache clean 33 | fi 34 | 35 | if command -v npm > /dev/null; then 36 | npm cache clean --force 37 | fi 38 | -------------------------------------------------------------------------------- /images/centos/scripts/build/cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: cleanup.sh 4 | ## Desc: Perform cleanup for CentOS 5 | ################################################################################ 6 | 7 | # before cleanup 8 | before=$(df / -Pm | awk 'NR==2{print $4}') 9 | 10 | # Clear the local repository of retrieved package files 11 | yum clean all 12 | rm -rf /var/cache/yum/* 13 | rm -rf /tmp/* 14 | rm -rf /root/.cache 15 | 16 | # Rotate and vacuum journal logs if `journalctl` is available 17 | if command -v journalctl; then 18 | journalctl --rotate 19 | journalctl --vacuum-time=1s 20 | fi 21 | 22 | # Delete all .gz and rotated files 23 | find /var/log -type f -regex ".*\.gz$" -delete 24 | find /var/log -type f -regex ".*\.[0-9]$" -delete 25 | 26 | # Wipe log files 27 | find /var/log/ -type f -exec cp /dev/null {} \; 28 | 29 | # Remove mock binaries for apt 30 | prefix=/usr/local/bin 31 | for tool in apt apt-get apt-key; do 32 | rm -f $prefix/$tool 33 | done 34 | 35 | # after cleanup 36 | after=$(df / -Pm | awk 'NR==2{print $4}') 37 | 38 | # Display size 39 | echo "Before: $before MB" 40 | echo "After : $after MB" 41 | # shellcheck disable=SC2004 42 | echo "Delta : $(($after - $before)) MB" 43 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-nodejs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-nodejs.sh 4 | ## Desc: Install Node.js LTS and related tooling (Gulp, Grunt) 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | # Install default Node.js 12 | default_version=$(get_toolset_value '.node.default') 13 | curl -fsSL https://raw.githubusercontent.com/tj/n/master/bin/n -o ~/n 14 | bash ~/n "$default_version" 15 | 16 | if [[ "$ARCH" == "ppc64le" || "$ARCH" == "s390x" ]]; then 17 | npm install -g grunt gulp n typescript newman vercel webpack webpack-cli yarn 18 | else 19 | # Install node modules 20 | node_modules=$(get_toolset_value '.node_modules[].name') 21 | npm install -g "$node_modules" 22 | fi 23 | 24 | echo "Creating the symlink for [now] command to vercel CLI" 25 | ln -s /usr/local/bin/vercel /usr/local/bin/now 26 | 27 | # fix global modules installation as regular user 28 | # related issue https://github.com/actions/runner-images/issues/3727 29 | sudo chmod -R 777 /usr/local/lib/node_modules 30 | sudo chmod -R 777 /usr/local/bin 31 | 32 | rm -rf ~/n 33 | -------------------------------------------------------------------------------- /scripts/helpers/setup_img.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e # Exit on any error 3 | 4 | CURRENT_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" 5 | IMGDIR="${CURRENT_DIR}/../../images/${IMAGE_OS}" 6 | 7 | # Check if /imagegeneration already exists, delete if so, and recreate 8 | # shellcheck disable=SC2154 9 | if [ -d "${image_folder}" ]; then 10 | echo "Directory ${image_folder} exists. Deleting and recreating it." 11 | sudo rm -rf "${image_folder}" 12 | fi 13 | 14 | # shellcheck disable=SC2154 15 | sudo mkdir -p "${installer_script_folder}" 16 | # shellcheck disable=SC2154 17 | sudo cp -r "${IMGDIR}"/scripts/helpers/. "${helper_script_folder}" 18 | sudo cp -r "${CURRENT_DIR}"/. "${helper_script_folder}" 19 | sudo cp -r "${CURRENT_DIR}"/../assets/. "${installer_script_folder}" 20 | sudo cp "${CURRENT_DIR}"/../../patches/"${PATCH_FILE}" "${image_folder}/runner-sdk-8.patch" 21 | # shellcheck disable=SC2154 22 | sudo cp "${IMGDIR}"/toolsets/"${toolset_file_name}" "${installer_script_folder}/toolset.json" 23 | sudo cp -r "${IMGDIR}"/scripts/build/. "${installer_script_folder}" 24 | sudo cp -r "${IMGDIR}"/assets/post-gen "${image_folder}" 25 | 26 | if [ ! -d "${image_folder}/post-generation" ]; then 27 | sudo mv "${image_folder}/post-gen" "${image_folder}/post-generation" 28 | fi 29 | sudo chmod -R 0755 "${image_folder}" -------------------------------------------------------------------------------- /.github/workflows/complete_lxd_build.yml: -------------------------------------------------------------------------------- 1 | name: complete LXD build 2 | 3 | # Controls when the workflow will run 4 | on: 5 | # Triggers the workflow on push or pull request events but only for the "main" branch 6 | push: 7 | branches: [ "main"] 8 | pull_request: 9 | branches: [ "main"] 10 | # Allows you to run this workflow manually from the Actions tab 11 | workflow_dispatch: 12 | 13 | jobs: 14 | gaplib-build: 15 | name: Run complete build - ${{ matrix.runner_name }} [${{ matrix.runner_owner }}] 16 | runs-on: ${{ matrix.runner_name }} 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | include: 21 | - os: "ubuntu" 22 | version: "24.04" 23 | runner_name: "ubuntu-24.04-ppc64le" 24 | runner_owner: "ppc64le-hosted" 25 | setup_type: "complete" 26 | - os: "ubuntu" 27 | version: "24.04" 28 | runner_name: "ubuntu-24.04-s390x" 29 | runner_owner: "s390x-hosted" 30 | setup_type: "complete" 31 | steps: 32 | - name: Checkout Code 33 | uses: actions/checkout@v5 34 | 35 | - name: Build Image 36 | run: | 37 | scripts/lxd.sh "${{ matrix.os }}" "${{ matrix.version }}" "" "" "${{ matrix.setup_type }}" --skip-snap-lxd --skip-lxd-snapshot 38 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-yq.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-yq.sh 4 | ## Desc: Install yq - a command-line YAML, JSON and XML processor 5 | ## Supply chain security: yq - checksum validation 6 | ################################################################################ 7 | 8 | # Source the helpers for use with the script 9 | # shellcheck disable=SC1091 10 | source "$HELPER_SCRIPTS"/install.sh 11 | 12 | # Set architecture-specific variables using a case statement for clarity 13 | case "$ARCH" in 14 | "x86_64") 15 | package_arch="amd64" 16 | ;; 17 | "ppc64le" | "s390x" | *) 18 | package_arch="$ARCH" 19 | ;; 20 | esac 21 | 22 | # Download yq for package_arch 23 | yq_url=$(resolve_github_release_asset_url "mikefarah/yq" "endswith(\"yq_linux_${package_arch}\")" "latest") 24 | binary_path=$(download_with_retry "${yq_url}") 25 | 26 | # Supply chain security - yq 27 | # hash_url=$(resolve_github_release_asset_url "mikefarah/yq" "endswith(\"checksums\")" "latest") 28 | # external_hash=$(get_checksum_from_url "${hash_url}" "yq_linux_${package_arch}" "SHA256" "true" " " "19") 29 | # use_checksum_comparison "$binary_path" "$external_hash" 30 | 31 | # Install yq 32 | install "$binary_path" /usr/bin/yq -------------------------------------------------------------------------------- /DCO.txt: -------------------------------------------------------------------------------- 1 | Developer's Certificate of Origin 1.1 2 | 3 | By making a contribution to this project, I certify that: 4 | 5 | (a) The contribution was created in whole or in part by me and I 6 | have the right to submit it under the open source license 7 | indicated in the file; or 8 | 9 | (b) The contribution is based upon previous work that, to the best 10 | of my knowledge, is covered under an appropriate open source 11 | license and I have the right under that license to submit that 12 | work with modifications, whether created in whole or in part 13 | by me, under the same open source license (unless I am 14 | permitted to submit under a different license), as indicated 15 | in the file; or 16 | 17 | (c) The contribution was provided directly to me by some other 18 | person who certified (a), (b) or (c) and I have not modified 19 | it. 20 | 21 | (d) I understand and agree that this project and the contribution 22 | are public and that a record of the contribution (including all 23 | personal information I submit with it, including my sign-off) is 24 | maintained indefinitely and may be redistributed consistent with 25 | this project or the open source license(s) involved. 26 | -------------------------------------------------------------------------------- /images/centos/scripts/build/install-actions-cache.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-actions-cache.sh 4 | ## Desc: Download latest release from https://github.com/actions/action-versions 5 | ## Maintainer: #actions-runtime and @TingluoHuang 6 | ################################################################################ 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | source "$HELPER_SCRIPTS"/etc-environment.sh 11 | 12 | # Prepare directory and env variable for ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE 13 | ACTION_ARCHIVE_CACHE_DIR=/opt/actionarchivecache 14 | mkdir -p $ACTION_ARCHIVE_CACHE_DIR 15 | chmod -R 777 $ACTION_ARCHIVE_CACHE_DIR 16 | echo "Setting up ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE variable to ${ACTION_ARCHIVE_CACHE_DIR}" 17 | set_etc_environment_variable "ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE" "${ACTION_ARCHIVE_CACHE_DIR}" 18 | 19 | # Download latest release from github.com/actions/action-versions and untar to /opt/actionarchivecache 20 | download_url=$(resolve_github_release_asset_url "actions/action-versions" "endswith(\"action-versions.tar.gz\")" "latest") 21 | archive_path=$(download_with_retry "$download_url") 22 | tar -xzf "$archive_path" -C $ACTION_ARCHIVE_CACHE_DIR 23 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/configure-apt-sources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: configure-apt-sources.sh 4 | ## Desc: Configure apt sources with failover from Azure to Ubuntu archives. 5 | ################################################################################ 6 | 7 | # shellcheck disable=SC1091 8 | source "$HELPER_SCRIPTS"/os.sh 9 | 10 | touch /etc/apt/apt-mirrors.txt 11 | 12 | printf "http://azure.archive.ubuntu.com/ubuntu/\tpriority:1\n" | tee -a /etc/apt/apt-mirrors.txt 13 | printf "https://archive.ubuntu.com/ubuntu/\tpriority:2\n" | tee -a /etc/apt/apt-mirrors.txt 14 | printf "https://security.ubuntu.com/ubuntu/\tpriority:3\n" | tee -a /etc/apt/apt-mirrors.txt 15 | 16 | if is_ubuntu24; then 17 | sed -i 's|http://azure\.archive\.ubuntu\.com/ubuntu/|mirror+file:/etc/apt/apt-mirrors.txt|' /etc/apt/sources.list.d/ubuntu.sources 18 | 19 | # Apt changes to survive Cloud Init 20 | cp -f /etc/apt/sources.list.d/ubuntu.sources /etc/cloud/templates/sources.list.ubuntu.deb822.tmpl 21 | else 22 | sed -i 's|http://azure\.archive\.ubuntu\.com/ubuntu/|mirror+file:/etc/apt/apt-mirrors.txt|' /etc/apt/sources.list 23 | 24 | # Apt changes to survive Cloud Init 25 | cp -f /etc/apt/sources.list /etc/cloud/templates/sources.list.ubuntu.tmpl 26 | fi 27 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-google-cloud-cli.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-google-cloud-cli.sh 4 | ## Desc: Install the Google Cloud CLI 5 | ################################################################################ 6 | # Source the helpers for use with the script 7 | # shellcheck disable=SC1091 8 | source "$HELPER_SCRIPTS"/install.sh 9 | 10 | # Set architecture-specific variables using a case statement for clarity 11 | case "$ARCH" in 12 | "ppc64le" | "s390x") 13 | echo "No actions defined for $ARCH architecture." 14 | exit 0 15 | ;; 16 | *) 17 | ;; 18 | esac 19 | 20 | REPO_URL="https://packages.cloud.google.com/apt" 21 | 22 | # Install the Google Cloud CLI 23 | echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] $REPO_URL cloud-sdk main" > /etc/apt/sources.list.d/google-cloud-sdk.list 24 | wget -qO- https://packages.cloud.google.com/apt/doc/apt-key.gpg | gpg --dearmor > /usr/share/keyrings/cloud.google.gpg 25 | update_dpkgs 26 | install_dpkgs google-cloud-cli 27 | 28 | # remove apt 29 | rm /etc/apt/sources.list.d/google-cloud-sdk.list 30 | rm /usr/share/keyrings/cloud.google.gpg 31 | 32 | # add repo to the apt-sources.txt 33 | echo "google-cloud-sdk $REPO_URL" >> "$HELPER_SCRIPTS"/apt-sources.txt 34 | -------------------------------------------------------------------------------- /images/centos/scripts/build/configure-dnf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: configure-dnf.sh 4 | ## Desc: Configure dnf/yum, install jq package, and improve package management behavior. 5 | ################################################################################ 6 | # Source the helpers for use with the script 7 | # shellcheck disable=SC1091 8 | source "$HELPER_SCRIPTS"/install.sh 9 | # Enable retries for DNF (maximum retries set to 10) 10 | # shellcheck disable=SC2129 11 | echo "retries=10" >> /etc/dnf/dnf.conf 12 | 13 | # Automatically assume 'yes' for prompts in DNF 14 | echo "assumeyes=True" >> /etc/dnf/dnf.conf 15 | 16 | # Configure DNF to always consider phased updates 17 | echo "phased_updates=1" >> /etc/dnf/dnf.conf 18 | 19 | # Fix potential bad proxy or HTTP headers settings 20 | cat <> /etc/dnf/dnf.conf 21 | http_caching=none 22 | EOF 23 | 24 | # Remove unattended-upgrade equivalents if present (e.g., dnf-automatic) 25 | dnf remove -y dnf-automatic 26 | 27 | # Display DNF repository configurations 28 | echo 'DNF/YUM repositories:' 29 | dnf repolist 30 | 31 | # Update repositories and install jq 32 | install_dnfpkgs jq 33 | 34 | # Optional: Configure parallel downloads to speed up package installation 35 | echo "max_parallel_downloads=10" >> /etc/dnf/dnf.conf -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-actions-cache.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-actions-cache.sh 4 | ## Desc: Download latest release from https://github.com/actions/action-versions 5 | ## Maintainer: #actions-runtime and @TingluoHuang 6 | ################################################################################ 7 | 8 | # Source the helpers for use with the script 9 | # shellcheck disable=SC1091 10 | source "$HELPER_SCRIPTS"/install.sh 11 | source "$HELPER_SCRIPTS"/etc-environment.sh 12 | 13 | # Prepare directory and env variable for ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE 14 | ACTION_ARCHIVE_CACHE_DIR=/opt/actionarchivecache 15 | mkdir -p $ACTION_ARCHIVE_CACHE_DIR 16 | chmod -R 777 $ACTION_ARCHIVE_CACHE_DIR 17 | echo "Setting up ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE variable to ${ACTION_ARCHIVE_CACHE_DIR}" 18 | set_etc_environment_variable "ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE" "${ACTION_ARCHIVE_CACHE_DIR}" 19 | 20 | # Download latest release from github.com/actions/action-versions and untar to /opt/actionarchivecache 21 | download_url=$(resolve_github_release_asset_url "actions/action-versions" "endswith(\"action-versions.tar.gz\")" "latest") 22 | archive_path=$(download_with_retry "$download_url") 23 | tar -xzf "$archive_path" -C $ACTION_ARCHIVE_CACHE_DIR 24 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-oras-cli.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-oras-cli.sh 4 | ## Desc: Install ORAS CLI 5 | ## Supply chain security: ORAS CLI - checksum validation 6 | ################################################################################ 7 | 8 | # Source the helpers for use with the script 9 | # shellcheck disable=SC1091 10 | source "$HELPER_SCRIPTS"/install.sh 11 | 12 | # Set architecture-specific variables using a case statement for clarity 13 | case "$ARCH" in 14 | "x86_64") 15 | package_arch="amd64" 16 | ;; 17 | "ppc64le" | "s390x" | *) 18 | package_arch="$ARCH" 19 | ;; 20 | esac 21 | 22 | # Determine latest ORAS CLI version 23 | download_url=$(resolve_github_release_asset_url "oras-project/oras" "endswith(\"linux_${package_arch}.tar.gz\")" "latest") 24 | 25 | # Download ORAS CLI 26 | archive_path=$(download_with_retry "$download_url") 27 | 28 | # Supply chain security - ORAS CLI 29 | hash_url=$(resolve_github_release_asset_url "oras-project/oras" "endswith(\"checksums.txt\")" "latest") 30 | external_hash=$(get_checksum_from_url "${hash_url}" "linux_${package_arch}.tar.gz" "SHA256") 31 | use_checksum_comparison "$archive_path" "${external_hash}" 32 | 33 | # Unzip ORAS CLI 34 | tar xzf "$archive_path" -C /usr/local/bin oras 35 | 36 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: cleanup.sh 4 | ## Desc: Perform cleanup 5 | ################################################################################ 6 | 7 | # before cleanup 8 | before=$(df / -Pm | awk 'NR==2{print $4}') 9 | 10 | # clears out the local repository of retrieved package files 11 | # It removes everything but the lock file from /var/cache/apt/archives/ and /var/cache/apt/archives/partial 12 | apt-get clean 13 | rm -rf /tmp/* 14 | rm -rf /root/.cache 15 | 16 | # journalctl 17 | if command -v journalctl; then 18 | journalctl --rotate 19 | journalctl --vacuum-time=1s 20 | fi 21 | 22 | # delete all .gz and rotated file 23 | find /var/log -type f -regex ".*\.gz$" -delete 24 | find /var/log -type f -regex ".*\.[0-9]$" -delete 25 | 26 | # wipe log files 27 | find /var/log/ -type f -exec cp /dev/null {} \; 28 | 29 | # delete symlink for tests running 30 | rm -f /usr/local/bin/invoke_tests 31 | 32 | # remove apt mock 33 | prefix=/usr/local/bin 34 | for tool in apt apt-get apt-key;do 35 | sudo rm -f $prefix/$tool 36 | done 37 | 38 | # after cleanup 39 | after=$(df / -Pm | awk 'NR==2{print $4}') 40 | 41 | # display size 42 | echo "Before: $before MB" 43 | echo "After : $after MB" 44 | # shellcheck disable=SC2004 45 | echo "Delta : $(($after-$before)) MB" 46 | -------------------------------------------------------------------------------- /images/centos/scripts/build/install-python.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-python.sh 4 | ## Desc: Install Python 3 5 | ################################################################################ 6 | 7 | set -e 8 | # Source the helpers for use with the script 9 | # shellcheck disable=SC1091 10 | source "$HELPER_SCRIPTS"/etc-environment.sh 11 | # shellcheck disable=SC1091 12 | source "$HELPER_SCRIPTS"/os.sh 13 | # shellcheck disable=SC1091 14 | source "$HELPER_SCRIPTS"/install.sh 15 | 16 | # Install Python, Python 3, pip, pip3 17 | install_dnfpkgs --no-install-recommends python3 python3-dev python3-pip python3-venv 18 | 19 | # Install pipx 20 | # Set pipx custom directory 21 | export PIPX_BIN_DIR=/opt/pipx_bin 22 | export PIPX_HOME=/opt/pipx 23 | 24 | python3 -m pip install pipx 25 | python3 -m pipx ensurepath 26 | 27 | # Update /etc/environment 28 | set_etc_environment_variable "PIPX_BIN_DIR" $PIPX_BIN_DIR 29 | set_etc_environment_variable "PIPX_HOME" $PIPX_HOME 30 | prepend_etc_environment_path $PIPX_BIN_DIR 31 | 32 | # Test pipx 33 | if ! command -v pipx; then 34 | echo "pipx was not installed or not found on PATH" 35 | exit 1 36 | fi 37 | 38 | # Adding this dir to PATH will make installed pip commands are immediately available. 39 | # shellcheck disable=SC2016 40 | prepend_etc_environment_path '$HOME/.local/bin' 41 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-vcpkg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-vcpkg.sh 4 | ## Desc: Install vcpkg 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/etc-environment.sh 10 | 11 | # Set architecture-specific variables using a case statement for clarity 12 | case "$ARCH" in 13 | "ppc64le" | "s390x") 14 | echo "No actions defined for $ARCH architecture." 15 | exit 0 16 | ;; 17 | *) 18 | ;; 19 | esac 20 | 21 | # Set env variable for vcpkg 22 | VCPKG_INSTALLATION_ROOT=/usr/local/share/vcpkg 23 | set_etc_environment_variable "VCPKG_INSTALLATION_ROOT" "${VCPKG_INSTALLATION_ROOT}" 24 | 25 | # Install vcpkg 26 | git clone https://github.com/Microsoft/vcpkg $VCPKG_INSTALLATION_ROOT 27 | 28 | $VCPKG_INSTALLATION_ROOT/bootstrap-vcpkg.sh 29 | 30 | # workaround https://github.com/microsoft/vcpkg/issues/27786 31 | 32 | mkdir -p /root/.vcpkg/ "$HOME"/.vcpkg 33 | touch /root/.vcpkg/vcpkg.path.txt "$HOME"/.vcpkg/vcpkg.path.txt 34 | 35 | $VCPKG_INSTALLATION_ROOT/vcpkg integrate install 36 | chmod 0777 -R $VCPKG_INSTALLATION_ROOT 37 | ln -sf $VCPKG_INSTALLATION_ROOT/vcpkg /usr/local/bin 38 | 39 | rm -rf /root/.vcpkg "$HOME"/.vcpkg 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-mono.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-mono.sh 4 | ## Desc: Install Mono 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/os.sh 10 | source "$HELPER_SCRIPTS"/install.sh 11 | 12 | os_label=$(lsb_release -cs) 13 | REPO_URL="https://download.mono-project.com/repo/ubuntu" 14 | GPG_KEY="/usr/share/keyrings/mono-official-stable.gpg" 15 | REPO_PATH="/etc/apt/sources.list.d/mono-official-stable.list" 16 | 17 | # There are no packages for Ubuntu 22 in the repo, but developers confirmed that packages from Ubuntu 20 should work 18 | if is_ubuntu22; then 19 | os_label="focal" 20 | fi 21 | 22 | # Install Mono repo 23 | curl -fsSL https://download.mono-project.com/repo/xamarin.gpg | gpg --dearmor -o $GPG_KEY 24 | echo "deb [signed-by=$GPG_KEY] $REPO_URL stable-$os_label main" > $REPO_PATH 25 | 26 | # Install Mono 27 | update_dpkgs 28 | install_dpkgs --no-install-recommends apt-transport-https mono-complete nuget 29 | 30 | # Remove Mono's apt repo 31 | rm $REPO_PATH 32 | rm -f "${REPO_PATH}.save" 33 | rm $GPG_KEY 34 | 35 | # Document source repo 36 | echo "mono https://download.mono-project.com/repo/ubuntu stable-$os_label main" >> "$HELPER_SCRIPTS"/apt-sources.txt 37 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-pulumi.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-pulumi.sh 4 | ## Desc: Install Pulumi 5 | ## Supply chain security: Pulumi - checksum validation 6 | ################################################################################ 7 | 8 | # Source the helpers for use with the script 9 | # shellcheck disable=SC1091 10 | source "$HELPER_SCRIPTS"/install.sh 11 | 12 | # Set architecture-specific variables using a case statement for clarity 13 | case "$ARCH" in 14 | "ppc64le" | "s390x") 15 | echo "No actions defined for $ARCH architecture." 16 | exit 0 17 | ;; 18 | "x86_64") 19 | package_arch="x64" 20 | ;; 21 | *) 22 | package_arch="$ARCH" 23 | ;; 24 | esac 25 | 26 | # Dowload Pulumi 27 | version=$(curl -fsSL "https://www.pulumi.com/latest-version") 28 | download_url="https://get.pulumi.com/releases/sdk/pulumi-v${version}-linux-${package_arch}.tar.gz" 29 | archive_path=$(download_with_retry "$download_url") 30 | 31 | # Supply chain security - Pulumi 32 | external_hash=$(get_checksum_from_url "https://github.com/pulumi/pulumi/releases/download/v${version}/SHA512SUMS" "linux-${package_arch}.tar.gz" "SHA512") 33 | use_checksum_comparison "$archive_path" "$external_hash" "512" 34 | 35 | # Unzipping Pulumi 36 | tar --strip=1 -xf "$archive_path" -C /usr/local/bin -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-postgresql.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-postgresql.sh 4 | ## Desc: Install PostgreSQL 5 | ################################################################################ 6 | 7 | # Source the helpers 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/os.sh 10 | source "$HELPER_SCRIPTS"/install.sh 11 | 12 | REPO_URL="https://apt.postgresql.org/pub/repos/apt/" 13 | 14 | # Preparing repo for PostgreSQL 15 | wget -qO - https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor > /usr/share/keyrings/postgresql.gpg 16 | echo "deb [signed-by=/usr/share/keyrings/postgresql.gpg] $REPO_URL $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list 17 | 18 | # Fetch PostgreSQL version to install from the toolset 19 | toolset_version=$(get_toolset_value '.postgresql.version') 20 | 21 | # Install PostgreSQL 22 | echo "Install PostgreSQL" 23 | update_dpkgs 24 | install_dpkgs postgresql-"$toolset_version" 25 | 26 | echo "Install libpq-dev" 27 | install_dpkgs libpq-dev 28 | 29 | # Disable postgresql.service 30 | systemctl is-active --quiet postgresql.service && systemctl stop postgresql.service 31 | systemctl disable postgresql.service 32 | 33 | rm /etc/apt/sources.list.d/pgdg.list 34 | rm /usr/share/keyrings/postgresql.gpg 35 | 36 | echo "postgresql $REPO_URL" >> "$HELPER_SCRIPTS"/apt-sources.txt 37 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to make participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | -------------------------------------------------------------------------------- /images/centos/scripts/build/configure-snap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: configure-snap.sh 4 | ## Desc: Configure snap 5 | ################################################################################ 6 | # Source the helpers for use with the script 7 | # shellcheck disable=SC1091 8 | source "$HELPER_SCRIPTS"/etc-environment.sh 9 | 10 | # Update /etc/environment to include /snap/bin in PATH 11 | # because /etc/profile.d is ignored by `--norc` shell launch option 12 | if [[ ":$PATH:" == *"/snap/bin"* ]]; then 13 | echo "/snap/bin is already in the PATH" 14 | else 15 | echo "/snap/bin is not in the PATH. Adding it now..." 16 | export PATH=/snap/bin:$PATH 17 | echo "export PATH=/snap/bin:$PATH" >> ~/.bashrc # Persist for future sessions 18 | echo "/snap/bin has been added to the PATH" 19 | fi 20 | # Put snapd auto refresh on hold 21 | # as it may generate too much traffic on Canonical's snap server 22 | # when they are rolling a new major update out. 23 | # Hold is calculated as today's date + 60 days 24 | 25 | # snapd is started automatically, but during image generation 26 | # a unix socket may die, restart snapd.service (and therefore snapd.socket) 27 | # to make sure the socket is alive. 28 | 29 | systemctl restart snapd.socket 30 | systemctl restart snapd 31 | snap set system refresh.hold="$(date --date='today+60 days' +%Y-%m-%dT%H:%M:%S%:z)" 32 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/configure-system.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: configure-system.sh 4 | ## Desc: Post deployment system configuration actions 5 | ################################################################################ 6 | # shellcheck disable=SC1091 7 | source "$HELPER_SCRIPTS"/etc-environment.sh 8 | source "$HELPER_SCRIPTS"/os.sh 9 | 10 | mv -f "${IMAGE_FOLDER}/post-generation" /opt 11 | 12 | echo "chmod -R 777 /opt" 13 | chmod -R 777 /opt 14 | echo "chmod -R 777 /usr/share" 15 | chmod -R 777 /usr/share 16 | 17 | chmod 755 "$IMAGE_FOLDER" 18 | 19 | # Remove quotes around PATH 20 | ENVPATH=$(grep 'PATH=' /etc/environment | head -n 1 | sed -z 's/^PATH=*//') 21 | ENVPATH=${ENVPATH#"\""} 22 | ENVPATH=${ENVPATH%"\""} 23 | replace_etc_environment_variable "PATH" "${ENVPATH}" 24 | echo "Updated /etc/environment: $(cat /etc/environment)" 25 | 26 | # Clean yarn and npm cache 27 | if yarn --version > /dev/null; then 28 | yarn cache clean 29 | fi 30 | 31 | if npm --version; then 32 | npm cache clean --force 33 | fi 34 | 35 | if is_ubuntu24; then 36 | # Prevent needrestart from restarting the provisioner service. 37 | # Currently only happens on Ubuntu 24.04, so make it conditional for the time being 38 | # as configuration is too different between Ubuntu versions. 39 | sed -i '/^\s*};/i \ qr(^runner-provisioner) => 0,' /etc/needrestart/needrestart.conf 40 | fi 41 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-sqlpackage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-sqlpackage.sh 4 | ## Desc: Install SqlPackage CLI to DacFx (https://docs.microsoft.com/sql/tools/sqlpackage/sqlpackage-download#get-sqlpackage-net-core-for-linux) 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | source "$HELPER_SCRIPTS"/os.sh 11 | 12 | # Set architecture-specific variables using a case statement for clarity 13 | case "$ARCH" in 14 | "ppc64le" | "s390x") 15 | echo "No actions defined for $ARCH architecture." 16 | exit 0 17 | ;; 18 | *) 19 | ;; 20 | esac 21 | 22 | # Install libssl1.1 dependency 23 | if is_ubuntu22; then 24 | focal_list=/etc/apt/sources.list.d/focal-security.list 25 | echo "deb http://archive.ubuntu.com/ubuntu/ focal-security main" | tee "${focal_list}" 26 | update_dpkgs 27 | 28 | install_dpkgs --no-install-recommends libssl1.1 29 | 30 | rm "${focal_list}" 31 | update_dpkgs 32 | fi 33 | 34 | # Install SqlPackage 35 | archive_path=$(download_with_retry "https://aka.ms/sqlpackage-linux") 36 | unzip -qq "$archive_path" -d /usr/local/sqlpackage 37 | chmod +x /usr/local/sqlpackage/sqlpackage 38 | ln -sf /usr/local/sqlpackage/sqlpackage /usr/local/bin 39 | 40 | -------------------------------------------------------------------------------- /images/centos/scripts/build/install-github-cli.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-github-cli.sh 4 | ## Desc: Install GitHub CLI 5 | ## Must be run as non-root user after homebrew 6 | ## Supply chain security: GitHub CLI - checksum validation 7 | ################################################################################ 8 | 9 | # Source the helpers for use with the script 10 | # shellcheck disable=SC1091 11 | source "$HELPER_SCRIPTS"/install.sh 12 | 13 | # Set architecture-specific variables using a case statement for clarity 14 | case "$ARCH" in 15 | "ppc64le" | "s390x") 16 | echo "No actions defined for $ARCH architecture." 17 | exit 0 18 | ;; 19 | "x86_64") 20 | package_arch="amd64" 21 | ;; 22 | *) 23 | package_arch="$ARCH" 24 | ;; 25 | esac 26 | 27 | # Download GitHub CLI 28 | gh_cli_url=$(resolve_github_release_asset_url "cli/cli" "contains(\"linux\") and contains(\"${package_arch}\") and endswith(\".deb\")" "latest") 29 | gh_cli_rpm_path=$(download_with_retry "$gh_cli_url") 30 | 31 | # Supply chain security - GitHub CLI 32 | hash_url=$(resolve_github_release_asset_url "cli/cli" "endswith(\"checksums.txt\")" "latest") 33 | external_hash=$(get_checksum_from_url "$hash_url" "linux_${package_arch}.rpm" "SHA256") 34 | use_checksum_comparison "$gh_cli_rpm_path" "$external_hash" 35 | 36 | # Install GitHub CLI 37 | install_dnfpkgs "$gh_cli_rpm_path" -------------------------------------------------------------------------------- /images/centos/scripts/build/configure-yum-mock.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: configure-yum-mock.sh 4 | ## Desc: A temporary workaround to handle transient issues with DNF/YUM. 5 | ## Cleaned up during cleanup.sh. 6 | ################################################################################ 7 | prefix=/usr/local/bin 8 | 9 | for real_tool in /usr/bin/yum /usr/bin/dnf; do 10 | tool=$(basename $real_tool) 11 | cat >$prefix/"$tool" <\$err 18 | 19 | # no errors, break the loop and continue normal flow 20 | test -f \$err || break 21 | cat \$err >&2 22 | 23 | retry=false 24 | 25 | if grep -q 'Could not get lock' \$err;then 26 | # DNF/YUM db locked needs retry 27 | retry=true 28 | elif grep -q 'Failed to download metadata' \$err;then 29 | # Repository metadata issue, needs retry 30 | retry=true 31 | elif grep -q 'Temporary failure in name resolution' \$err;then 32 | # DNS resolution issue 33 | retry=true 34 | elif grep -q 'Package is being held by another process' \$err;then 35 | # DNF/YUM process is busy by another process 36 | retry=true 37 | fi 38 | 39 | rm \$err 40 | if [ \$retry = false ]; then 41 | break 42 | fi 43 | 44 | sleep 5 45 | echo "...retry \$i" 46 | i=\$((i + 1)) 47 | done 48 | EOT 49 | chmod +x $prefix/"$tool" 50 | done 51 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-github-cli.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-github-cli.sh 4 | ## Desc: Install GitHub CLI 5 | ## Must be run as non-root user after homebrew 6 | ## Supply chain security: GitHub CLI - checksum validation 7 | ################################################################################ 8 | 9 | # Source the helpers for use with the script 10 | # shellcheck disable=SC1091 11 | source "$HELPER_SCRIPTS"/install.sh 12 | 13 | # Set architecture-specific variables using a case statement for clarity 14 | case "$ARCH" in 15 | "ppc64le" | "s390x") 16 | echo "No actions defined for $ARCH architecture." 17 | exit 0 18 | ;; 19 | "x86_64") 20 | package_arch="amd64" 21 | ;; 22 | *) 23 | package_arch="$ARCH" 24 | ;; 25 | esac 26 | 27 | # Download GitHub CLI 28 | gh_cli_url=$(resolve_github_release_asset_url "cli/cli" "contains(\"linux\") and contains(\"${package_arch}\") and endswith(\".deb\")" "latest") 29 | gh_cli_deb_path=$(download_with_retry "$gh_cli_url") 30 | 31 | # Supply chain security - GitHub CLI 32 | hash_url=$(resolve_github_release_asset_url "cli/cli" "endswith(\"checksums.txt\")" "latest") 33 | external_hash=$(get_checksum_from_url "$hash_url" "linux_${package_arch}.deb" "SHA256") 34 | use_checksum_comparison "$gh_cli_deb_path" "$external_hash" 35 | 36 | # Install GitHub CLI 37 | install_dpkgs "$gh_cli_deb_path" 38 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-aliyun-cli.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-aliyun-cli.sh 4 | ## Desc: Install Alibaba Cloud CLI 5 | ## Supply chain security: Alibaba Cloud CLI - checksum validation 6 | ################################################################################ 7 | 8 | # Source the helpers for use with the script 9 | # shellcheck disable=SC1091 10 | source "$HELPER_SCRIPTS"/os.sh 11 | source "$HELPER_SCRIPTS"/install.sh 12 | 13 | # Set architecture-specific variables using a case statement for clarity 14 | case "$ARCH" in 15 | "ppc64le" | "s390x") 16 | echo "No actions defined for $ARCH architecture." 17 | exit 0 18 | ;; 19 | "x86_64") 20 | package_arch="amd64" 21 | ;; 22 | *) 23 | package_arch="$ARCH" 24 | ;; 25 | esac 26 | 27 | # Install Alibaba Cloud CLI 28 | 29 | download_url=$(resolve_github_release_asset_url "aliyun/aliyun-cli" "contains(\"aliyun-cli-linux\") and endswith(\"${package_arch}.tgz\")" "latest") 30 | hash_url="https://github.com/aliyun/aliyun-cli/releases/latest/download/SHASUMS256.txt" 31 | 32 | archive_path=$(download_with_retry "$download_url") 33 | 34 | # Supply chain security - Alibaba Cloud CLI 35 | external_hash=$(get_checksum_from_url "$hash_url" "aliyun-cli-linux.*${package_arch}.tgz" "SHA256") 36 | 37 | use_checksum_comparison "$archive_path" "$external_hash" 38 | 39 | tar xzf "$archive_path" 40 | mv aliyun /usr/local/bin -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-homebrew.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-homebrew.sh 4 | ## Desc: Install Homebrew on Linux 5 | ## Caveat: Brew MUST NOT be used to install any tool during the image build to avoid dependencies, which may come along with the tool 6 | ################################################################################ 7 | 8 | # Source the helpers 9 | # shellcheck disable=SC1091 10 | source "$HELPER_SCRIPTS"/etc-environment.sh 11 | source "$HELPER_SCRIPTS"/install.sh 12 | 13 | # Set architecture-specific variables using a case statement for clarity 14 | case "$ARCH" in 15 | "ppc64le" | "s390x") 16 | echo "No actions defined for $ARCH architecture." 17 | exit 0 18 | ;; 19 | *) 20 | ;; 21 | esac 22 | 23 | # Install the Homebrew on Linux 24 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" 25 | 26 | # Invoke shellenv to make brew available during running session 27 | eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" 28 | 29 | set_etc_environment_variable HOMEBREW_NO_AUTO_UPDATE 1 30 | set_etc_environment_variable HOMEBREW_CLEANUP_PERIODIC_FULL_DAYS 3650 31 | 32 | # Validate the installation ad hoc 33 | echo "Validate the installation reloading /etc/environment" 34 | reload_etc_environment 35 | 36 | gfortran=$(brew --prefix)/bin/gfortran 37 | # Remove gfortran symlink, not to conflict with system gfortran 38 | if [[ -e $gfortran ]]; then 39 | rm "$gfortran" 40 | fi 41 | -------------------------------------------------------------------------------- /images/centos/scripts/build/install-homebrew.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-homebrew.sh 4 | ## Desc: Install Homebrew on Linux 5 | ## Caveat: Brew MUST NOT be used to install any tool during the image build to avoid dependencies, which may come along with the tool 6 | ################################################################################ 7 | 8 | # Source the helpers 9 | # shellcheck disable=SC1091 10 | source "$HELPER_SCRIPTS"/etc-environment.sh 11 | source "$HELPER_SCRIPTS"/install.sh 12 | 13 | # Set architecture-specific variables using a case statement for clarity 14 | case "$ARCH" in 15 | "ppc64le" | "s390x") 16 | echo "No actions defined for $ARCH architecture." 17 | exit 0 18 | ;; 19 | *) 20 | ;; 21 | esac 22 | 23 | # Install the Homebrew on Linux 24 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" 25 | 26 | # Invoke shellenv to make brew available during running session 27 | eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" 28 | 29 | set_etc_environment_variable HOMEBREW_NO_AUTO_UPDATE 1 30 | set_etc_environment_variable HOMEBREW_CLEANUP_PERIODIC_FULL_DAYS 3650 31 | 32 | # Validate the installation ad hoc 33 | echo "Validate the installation reloading /etc/environment" 34 | reload_etc_environment 35 | 36 | gfortran=$(brew --prefix)/bin/gfortran 37 | # Remove gfortran symlink, not to conflict with system gfortran 38 | if [[ -e $gfortran ]]; then 39 | rm "$gfortran" 40 | fi 41 | 42 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-zstd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-zstd.sh 4 | ## Desc: Install zstd 5 | ## Supply chain security: zstd - checksum validation 6 | ################################################################################ 7 | 8 | # Source the helpers for use with the script 9 | # shellcheck disable=SC1091 10 | source "$HELPER_SCRIPTS"/install.sh 11 | 12 | # Download zstd 13 | release_tag=$(curl -fsSL https://api.github.com/repos/facebook/zstd/releases/latest | jq -r '.tag_name') 14 | release_name="zstd-${release_tag//v}" 15 | download_url="https://github.com/facebook/zstd/releases/download/${release_tag}/${release_name}.tar.gz" 16 | archive_path=$(download_with_retry "${download_url}") 17 | 18 | # Supply chain security - zstd 19 | external_hash=$(get_checksum_from_url "${download_url}.sha256" "${release_name}.tar.gz" "SHA256") 20 | use_checksum_comparison "$archive_path" "$external_hash" 21 | 22 | # Install zstd 23 | install_dpkgs liblz4-dev 24 | tar xzf "$archive_path" -C /tmp 25 | 26 | # shellcheck disable=SC2046 27 | make -C "/tmp/${release_name}/contrib/pzstd" -j $(nproc) all 28 | # shellcheck disable=SC2046 29 | make -C "/tmp/${release_name}" -j $(nproc) zstd-release 30 | 31 | for copyprocess in zstd zstdless zstdgrep; do 32 | cp "/tmp/${release_name}/programs/${copyprocess}" /usr/local/bin/ 33 | done 34 | 35 | cp "/tmp/${release_name}/contrib/pzstd/pzstd" /usr/local/bin/ 36 | 37 | for symlink in zstdcat zstdmt unzstd; do 38 | ln -sf /usr/local/bin/zstd /usr/local/bin/${symlink} 39 | done 40 | -------------------------------------------------------------------------------- /images/centos/scripts/build/install-zstd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-zstd.sh 4 | ## Desc: Install zstd 5 | ## Supply chain security: zstd - checksum validation 6 | ################################################################################ 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | # Download zstd 12 | release_tag=$(curl -fsSL https://api.github.com/repos/facebook/zstd/releases/latest | jq -r '.tag_name') 13 | release_name="zstd-${release_tag//v}" 14 | download_url="https://github.com/facebook/zstd/releases/download/${release_tag}/${release_name}.tar.gz" 15 | archive_path=$(download_with_retry "${download_url}") 16 | 17 | # Supply chain security - zstd 18 | external_hash=$(get_checksum_from_url "${download_url}.sha256" "${release_name}.tar.gz" "SHA256") 19 | use_checksum_comparison "$archive_path" "$external_hash" 20 | 21 | # Install dependencies 22 | install_dnfpkgs lz4-devel gcc make 23 | 24 | # Extract and build zstd 25 | tar xzf "$archive_path" -C /tmp 26 | 27 | make -C "/tmp/${release_name}/contrib/pzstd" all 28 | make -C "/tmp/${release_name}" zstd-release 29 | 30 | # Copy binaries 31 | for copyprocess in zstd zstdless zstdgrep; do 32 | sudo cp "/tmp/${release_name}/programs/${copyprocess}" /usr/local/bin/ 33 | done 34 | 35 | sudo cp "/tmp/${release_name}/contrib/pzstd/pzstd" /usr/local/bin/ 36 | 37 | # Create symlinks 38 | for symlink in zstdcat zstdmt unzstd; do 39 | sudo ln -sf /usr/local/bin/zstd /usr/local/bin/${symlink} 40 | done 41 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-cmake.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-cmake.sh 4 | ## Desc: Install CMake 5 | ## Supply chain security: CMake - checksum validation 6 | ################################################################################ 7 | 8 | # Source the helpers for use with the script 9 | # shellcheck disable=SC1091 10 | source "$HELPER_SCRIPTS"/install.sh 11 | 12 | # Test to see if the software in question is already installed, if not install it 13 | echo "Checking to see if the installer script has already been run" 14 | if command -v cmake; then 15 | echo "cmake is already installed" 16 | else 17 | # Set architecture-specific variables using a case statement for clarity 18 | case "$ARCH" in 19 | "ppc64le" | "s390x") 20 | install_dpkgs cmake 21 | exit 0 22 | ;; 23 | *) 24 | package_arch="$ARCH" 25 | ;; 26 | esac 27 | # Download script to install CMake 28 | download_url=$(resolve_github_release_asset_url "Kitware/CMake" "endswith(\"inux-${package_arch}.sh\")" "latest") 29 | curl -fsSL "${download_url}" -o cmakeinstall.sh 30 | 31 | # Supply chain security - CMake 32 | hash_url=$(resolve_github_release_asset_url "Kitware/CMake" "endswith(\"SHA-256.txt\")" "latest") 33 | external_hash=$(get_checksum_from_url "$hash_url" "linux-${package_arch}.sh" "SHA256") 34 | use_checksum_comparison "cmakeinstall.sh" "$external_hash" 35 | 36 | # Install CMake and remove the install script 37 | chmod +x cmakeinstall.sh \ 38 | && ./cmakeinstall.sh --prefix=/usr/local --exclude-subdir \ 39 | && rm cmakeinstall.sh 40 | fi 41 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-snap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-snap.sh 4 | ## Desc: Install snapd 5 | ################################################################################ 6 | # shellcheck disable=SC1091 7 | source "$HELPER_SCRIPTS"/install.sh 8 | 9 | # Install snapd if not already installed 10 | echo "Installing snapd..." 11 | if ! dpkg -l | grep -q snapd; then 12 | update_dpkgs 13 | install_dpkgs snapd 14 | else 15 | echo "snapd is already installed." 16 | fi 17 | 18 | # Enable and start snapd socket 19 | echo "Enabling and starting snapd.socket..." 20 | sudo systemctl enable --now snapd.socket 21 | 22 | # Create symbolic link for snap directory if not already exists 23 | if [ ! -L /snap ]; then 24 | echo "Creating symbolic link for /snap..." 25 | sudo ln -s /var/lib/snapd/snap /snap 26 | else 27 | echo "Symbolic link for /snap already exists." 28 | fi 29 | 30 | # Ensure /snap/bin is in the PATH 31 | echo "Checking if /snap/bin is in the PATH..." 32 | if [[ "$PATH" != *"/snap/bin"* ]]; then 33 | echo "/snap/bin is not in the PATH. Adding it now..." 34 | export PATH=/snap/bin:$PATH 35 | echo "export PATH=/snap/bin:$PATH" >> ~/.bashrc # Persist for future sessions 36 | echo "/snap/bin has been added to the PATH." 37 | else 38 | echo "/snap/bin is already in the PATH." 39 | fi 40 | 41 | echo "Checking the status of snapd.seeded.service..." 42 | ensure_service_is_active snapd.seeded.service 43 | ensure_service_is_active snapd.service 44 | 45 | echo "Snapd setup and initialization completed successfully." -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-python.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-python.sh 4 | ## Desc: Install Python 3 5 | ################################################################################ 6 | 7 | set -e 8 | # Source the helpers for use with the script 9 | # shellcheck disable=SC1091 10 | source "$HELPER_SCRIPTS"/etc-environment.sh 11 | # shellcheck disable=SC1091 12 | source "$HELPER_SCRIPTS"/os.sh 13 | # shellcheck disable=SC1091 14 | source "$HELPER_SCRIPTS"/install.sh 15 | 16 | # Install Python, Python 3, pip, pip3 17 | install_dpkgs --no-install-recommends python3 python3-dev python3-pip python3-venv 18 | 19 | if is_ubuntu24; then 20 | # Create temporary workaround to allow user to continue using pip 21 | # shellcheck disable=SC2024 22 | sudo cat < /etc/pip.conf 23 | [global] 24 | break-system-packages = true 25 | EOF 26 | fi 27 | 28 | # Install pipx 29 | # Set pipx custom directory 30 | export PIPX_BIN_DIR=/opt/pipx_bin 31 | export PIPX_HOME=/opt/pipx 32 | 33 | python3 -m pip install pipx 34 | python3 -m pipx ensurepath 35 | 36 | # Update /etc/environment 37 | set_etc_environment_variable "PIPX_BIN_DIR" $PIPX_BIN_DIR 38 | set_etc_environment_variable "PIPX_HOME" $PIPX_HOME 39 | prepend_etc_environment_path $PIPX_BIN_DIR 40 | 41 | # Test pipx 42 | if ! command -v pipx; then 43 | echo "pipx was not installed or not found on PATH" 44 | exit 1 45 | fi 46 | 47 | # Adding this dir to PATH will make installed pip commands are immediately available. 48 | # shellcheck disable=SC2016 49 | prepend_etc_environment_path '$HOME/.local/bin' 50 | -------------------------------------------------------------------------------- /images/centos/scripts/build/install-snap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-snap.sh 4 | ## Desc: Install snapd 5 | ################################################################################ 6 | # shellcheck disable=SC1091 7 | source "$HELPER_SCRIPTS"/install.sh 8 | 9 | # Install snapd if not already installed 10 | echo "Installing snapd..." 11 | if ! rpm -q snapd &>/dev/null; then 12 | update_dnfpkgs 13 | install_dnfpkgs epel-release snapd 14 | else 15 | echo "snapd is already installed." 16 | fi 17 | 18 | # Enable and start snapd.socket 19 | echo "Enabling and starting snapd.socket..." 20 | sudo systemctl enable --now snapd.socket 21 | 22 | # Create symbolic link for snap directory if not already exists 23 | if [ ! -L /snap ]; then 24 | echo "Creating symbolic link for /snap..." 25 | sudo ln -s /var/lib/snapd/snap /snap 26 | else 27 | echo "Symbolic link for /snap already exists." 28 | fi 29 | 30 | # Ensure /snap/bin is in the PATH 31 | echo "Checking if /snap/bin is in the PATH..." 32 | if [[ "$PATH" != *"/snap/bin"* ]]; then 33 | echo "/snap/bin is not in the PATH. Adding it now..." 34 | export PATH=/snap/bin:$PATH 35 | echo "export PATH=/snap/bin:$PATH" >> ~/.bashrc # Persist for future sessions 36 | echo "/snap/bin has been added to the PATH." 37 | else 38 | echo "/snap/bin is already in the PATH." 39 | fi 40 | 41 | echo "Checking the status of snapd.seeded.service..." 42 | ensure_service_is_active snapd.seeded.service 43 | ensure_service_is_active snapd.service 44 | 45 | echo "Snapd setup and initialization completed successfully." -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-lxd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-lxd.sh 4 | ## Desc: Install lxd 5 | ################################################################################ 6 | # shellcheck disable=SC1091 7 | source "$HELPER_SCRIPTS"/install.sh 8 | 9 | LATEST_LTS_CHANNEL=$(snap info lxd | grep -E '(^\s*[0-9]+\.0/stable)' | awk '{print $1}' | sed 's|/stable:||' | sort -rV | head -n 1) 10 | 11 | if [ -n "$LATEST_LTS_CHANNEL" ]; then 12 | echo "The latest LTS channel is: ${LATEST_LTS_CHANNEL}/stable" 13 | else 14 | echo "Could not determine the latest LTS channel." 15 | fi 16 | 17 | # Install 5.21 LTS LXD version using snap 18 | echo "Installing LXD version ${LATEST_LTS_CHANNEL} using snap..." 19 | sudo snap install lxd --channel="${LATEST_LTS_CHANNEL}/stable" 20 | 21 | echo "Checking list of refreshable snaps..." 22 | sudo snap refresh --list 23 | 24 | echo "Checking the status of snap.lxd.daemon..." 25 | ensure_service_is_active snap.lxd.daemon 26 | 27 | # Hold the autorefresh for LXD as it can cause unwanted service-disruptions 28 | sudo snap refresh --hold lxd 29 | 30 | # Initialize LXD using the preseed configuration file for automated setup. 31 | echo "Initializing LXD with preseed configuration..." 32 | if [[ -f "$INSTALLER_SCRIPT_FOLDER/lxd-preseed.yaml" ]]; then 33 | # shellcheck disable=SC2002 34 | cat "$INSTALLER_SCRIPT_FOLDER/lxd-preseed.yaml" | sudo lxd init --preseed 35 | else 36 | echo "Warning: lxd-preseed.yaml not found. Initializing with defaults." 37 | sudo lxd init --auto 38 | fi 39 | 40 | echo "LXD installation and initialization are complete!" -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-clang.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-clang.sh 4 | ## Desc: Install Clang compiler 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | install_clang() { 11 | local version=$1 12 | 13 | echo "Installing clang-$version..." 14 | install_dpkgs "clang-$version" "lldb-$version" "lld-$version" "clang-format-$version" "clang-tidy-$version" 15 | } 16 | 17 | set_default_clang() { 18 | local version=$1 19 | 20 | echo "Make Clang ${version} default" 21 | update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-"${version}" 100 22 | update-alternatives --install /usr/bin/clang clang /usr/bin/clang-"${version}" 100 23 | update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-"${version}" 100 24 | update-alternatives --install /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-"${version}" 100 25 | update-alternatives --install /usr/bin/run-clang-tidy run-clang-tidy /usr/bin/run-clang-tidy-"${version}" 100 26 | } 27 | 28 | versions=$(get_toolset_value '.clang.versions[]') 29 | default_clang_version=$(get_toolset_value '.clang.default_version') 30 | 31 | # shellcheck disable=SC2048 32 | for version in ${versions[*]}; do 33 | # shellcheck disable=SC2053 34 | if [[ $version != $default_clang_version ]]; then 35 | install_clang "$version" 36 | fi 37 | done 38 | 39 | install_clang "$default_clang_version" 40 | set_default_clang "$default_clang_version" 41 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-julia.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-julia.sh 4 | ## Desc: Install Julia and add to the path 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | # Set architecture-specific variables using a case statement for clarity 12 | case "$ARCH" in 13 | "ppc64le") 14 | triplet="powerpc64le-linux-gnu" 15 | tar_arch_suffix="linux-ppc64le" 16 | ;; 17 | "s390x") 18 | echo "Julia is not officially available for the s390x architecture." 19 | exit 0 20 | ;; 21 | "x86_64" | *) 22 | triplet="$ARCH-linux-gnu" 23 | tar_arch_suffix="linux-$ARCH" 24 | ;; 25 | esac 26 | 27 | # get the latest julia version 28 | json=$(curl -fsSL "https://julialang-s3.julialang.org/bin/versions.json") 29 | julia_version=$(echo "$json" | jq -r --arg triplet "$triplet" '.[].files[] | select(.triplet==$triplet and (.version | contains("-") | not)).version' | sort -V | tail -n1) 30 | 31 | # download julia archive 32 | julia_tar_url=$(echo "$json" | jq -r ".[].files[].url | select(endswith(\"julia-${julia_version}-${tar_arch_suffix}.tar.gz\"))") 33 | julia_archive_path=$(download_with_retry "$julia_tar_url") 34 | 35 | # extract files and make symlink 36 | julia_installation_path="/usr/local/julia${julia_version}" 37 | mkdir -p "${julia_installation_path}" 38 | tar -C "${julia_installation_path}" -xzf "$julia_archive_path" --strip-components=1 39 | ln -s "${julia_installation_path}/bin/julia" /usr/bin/julia 40 | -------------------------------------------------------------------------------- /images/centos/scripts/build/install-lxd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-lxd.sh 4 | ## Desc: Install lxd 5 | ################################################################################ 6 | # shellcheck disable=SC1091 7 | source "$HELPER_SCRIPTS"/install.sh 8 | 9 | LATEST_LTS_CHANNEL=$(snap info lxd | grep -E '(^\s*[0-9]+\.0/stable)' | awk '{print $1}' | sed 's|/stable:||' | sort -rV | head -n 1) 10 | 11 | if [ -n "$LATEST_LTS_CHANNEL" ]; then 12 | echo "The latest LTS channel is: ${LATEST_LTS_CHANNEL}/stable" 13 | else 14 | echo "Could not determine the latest LTS channel." 15 | fi 16 | 17 | # Install 5.21 LTS LXD version using snap 18 | echo "Installing LXD version ${LATEST_LTS_CHANNEL} using snap..." 19 | sudo snap install lxd --channel="${LATEST_LTS_CHANNEL}/stable" 20 | 21 | echo "Printing LXD info..." 22 | lxc info 23 | 24 | echo "Checking list of refreshable snaps..." 25 | sudo snap refresh --list 26 | 27 | echo "Checking the status of snap.lxd.daemon..." 28 | ensure_service_is_active snap.lxd.daemon 29 | 30 | # Hold the autorefresh for LXD as it can cause unwanted service-disruptions 31 | sudo snap refresh --hold lxd 32 | 33 | # Initialize LXD using the preseed configuration file for automated setup. 34 | echo "Initializing LXD with preseed configuration..." 35 | if [[ -f "$INSTALLER_SCRIPT_FOLDER/lxd-preseed.yaml" ]]; then 36 | # shellcheck disable=SC2002 37 | cat "$INSTALLER_SCRIPT_FOLDER/lxd-preseed.yaml" | sudo lxd init --preseed 38 | else 39 | echo "Warning: lxd-preseed.yaml not found. Initializing with defaults." 40 | sudo lxd init --auto 41 | fi 42 | 43 | echo "LXD installation and initialization are complete!" -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/configure-apt-mock.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: configure-apt-mock.sh 4 | ## Desc: A temporary workaround for https://github.com/Azure/azure-linux-extensions/issues/1238. 5 | ## Cleaned up during cleanup.sh. 6 | ################################################################################ 7 | 8 | prefix=/usr/local/bin 9 | 10 | for real_tool in /usr/bin/apt /usr/bin/apt-get /usr/bin/apt-key; do 11 | tool=$(basename $real_tool) 12 | cat >$prefix/"$tool" <\$err 19 | 20 | # no errors, break the loop and continue normal flow 21 | test -f \$err || break 22 | cat \$err >&2 23 | 24 | retry=false 25 | 26 | if grep -q 'Could not get lock' \$err;then 27 | # apt db locked needs retry 28 | retry=true 29 | elif grep -q 'Could not open file /var/lib/apt/lists' \$err;then 30 | # apt update is not completed, needs retry 31 | retry=true 32 | elif grep -q 'IPC connect call failed' \$err;then 33 | # the delay should help with gpg-agent not ready 34 | retry=true 35 | elif grep -q 'Temporary failure in name resolution' \$err;then 36 | # It looks like DNS is not updated with random generated hostname yet 37 | retry=true 38 | elif grep -q 'dpkg frontend is locked by another process' \$err;then 39 | # dpkg process is busy by another process 40 | retry=true 41 | fi 42 | 43 | rm \$err 44 | if [ \$retry = false ]; then 45 | break 46 | fi 47 | 48 | sleep 5 49 | echo "...retry \$i" 50 | i=\$((i + 1)) 51 | done 52 | EOT 53 | chmod +x $prefix/"$tool" 54 | done 55 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-container-tools.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-container-tools.sh 4 | ## Desc: Install container tools: podman, buildah and skopeo onto the image 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/os.sh 10 | source "$HELPER_SCRIPTS"/install.sh 11 | 12 | # Set architecture-specific variables using a case statement for clarity 13 | case "$ARCH" in 14 | "x86_64") 15 | package_arch="amd64" 16 | ;; 17 | *) 18 | package_arch="$ARCH" 19 | ;; 20 | esac 21 | 22 | # 23 | # pin podman due to https://github.com/actions/runner-images/issues/7753 24 | # https://bugs.launchpad.net/ubuntu/+source/libpod/+bug/2024394 25 | # 26 | if ! is_ubuntu22; then 27 | install_packages=(podman buildah skopeo) 28 | else 29 | install_packages=(podman=3.4.4+ds1-1ubuntu1 buildah skopeo) 30 | fi 31 | 32 | if is_ubuntu22 && [ "$ARCH" != "ppc64le" ] && [ "$ARCH" != "s390x" ]; then 33 | # Install containernetworking-plugins for Ubuntu 22 34 | curl -O http://archive.ubuntu.com/ubuntu/pool/universe/g/golang-github-containernetworking-plugins/containernetworking-plugins_1.1.1+ds1-3build1_"${package_arch}".deb 35 | dpkg -i containernetworking-plugins_1.1.1+ds1-3build1_"${package_arch}".deb 36 | fi 37 | 38 | # Install podman, buildah, skopeo container's tools 39 | update_dpkgs 40 | install_dpkgs "${install_packages[@]}" 41 | mkdir -p /etc/containers 42 | printf "[registries.search]\nregistries = ['docker.io', 'quay.io']\n" | tee /etc/containers/registries.conf 43 | 44 | -------------------------------------------------------------------------------- /dockerfiles/Dockerfile.centos.9: -------------------------------------------------------------------------------- 1 | # FROM quay.io/centos/centos:stream9 2 | FROM almalinux:9 3 | 4 | ARG RUNNERREPO="https://github.com/actions/runner" 5 | ARG RUNNERPATCH 6 | ARG SDK=8 7 | ARG ARCH 8 | 9 | RUN echo "tsflags=nodocs" >>/etc/dnf/dnf.conf 10 | 11 | RUN dnf update -y -q && \ 12 | dnf install -y -q \ 13 | wget git which langpacks-en glibc-all-langpacks sudo shadow-utils tar dotnet-sdk-${SDK}.0 \ 14 | cmake make automake autoconf m4 gcc gcc-c++ libtool epel-release && \ 15 | dnf clean all && \ 16 | rm -rf /var/cache/dnf/* 17 | 18 | RUN echo "Using SDK - $(dotnet --version)" 19 | 20 | ADD ${RUNNERPATCH} /tmp/runner.patch 21 | 22 | RUN cd /tmp && \ 23 | git clone --tags -q ${RUNNERREPO} && \ 24 | cd runner && \ 25 | git checkout $(git tag --sort=-v:refname | grep '^v[0-9]' | head -n1) && \ 26 | git apply --whitespace=nowarn /tmp/runner.patch && \ 27 | sed -i'' -e /version/s/8......\"$/8.0.100\"/ src/global.json 28 | 29 | RUN cd /tmp/runner/src && \ 30 | ./dev.sh layout Release && \ 31 | ./dev.sh package Release && \ 32 | ./dev.sh test && \ 33 | rm -rf /root/.dotnet /root/.nuget 34 | 35 | RUN useradd -c 'Action Runner' -m -s /bin/bash runner && \ 36 | usermod -L runner && \ 37 | echo 'runner ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/runner && \ 38 | chmod 440 /etc/sudoers.d/runner 39 | 40 | RUN mkdir -p /opt/runner-cache && \ 41 | tar -xf /tmp/runner/_package/*.tar.gz -C /opt/runner-cache && \ 42 | chown -R runner:runner /opt/runner-cache && \ 43 | sudo -u runner /opt/runner-cache/config.sh --version 44 | 45 | RUN rm -rf /tmp/runner /tmp/runner.patch 46 | 47 | USER runner 48 | 49 | EXPOSE 443 50 | 51 | CMD ["/bin/bash"] 52 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/configure-image-data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: configure-image-data.sh 4 | ## Desc: Create a file with image data and documentation links 5 | ################################################################################ 6 | 7 | # shellcheck disable=SC2153 8 | imagedata_file=$IMAGEDATA_FILE 9 | image_version=$IMAGE_VERSION 10 | image_version_major=${image_version/.*/} 11 | image_version_minor=$(echo "$image_version" | cut -d "." -f 2) 12 | os_name=$(lsb_release -ds | sed "s/ /\\\n/g") 13 | os_version=$(lsb_release -rs) 14 | image_label="ubuntu-${os_version}" 15 | version_major=${os_version/.*/} 16 | version_wo_dot=${os_version/./} 17 | 18 | github_url="https://github.com/IBM/action-runner-image-pz/blob/main/images" 19 | software_url="${github_url}/ubuntu/toolsets/toolset-${image_version_major}${image_version_minor}.json" 20 | releaseUrl="https://github.com/IBM/action-runner-image-pz/releases/tag/ubuntu${version_major}%2F${image_version_major}.${image_version_minor}" 21 | 22 | ## Following are custom values for P/Z self-hosted runners 23 | ## todo: extend this with CI build number 24 | runner_image_version="$(date +%Y%m%d)" 25 | image_build_date=$(date -u +"%Y-%m-%dT%H:%M:%SZ") 26 | image_builder_id=$(cat /etc/machine-id 2>/dev/null || hostname -s 2>/dev/null) 27 | 28 | cat < "$imagedata_file" 29 | [ 30 | { 31 | "group": "Runner Image Provisioner", 32 | "detail": "Commit: ${BUILD_SHA}\nBuild Date: ${image_build_date}\nBuilder ID: ${image_builder_id}" 33 | }, 34 | { 35 | "group": "Operating System", 36 | "detail": "${os_name}" 37 | }, 38 | { 39 | "group": "Runner Image", 40 | "detail": "Image: ${image_label}\nVersion: ${runner_image_version}\nIncluded Software: ${software_url}\nImage Release: ${releaseUrl}" 41 | } 42 | ] 43 | EOF -------------------------------------------------------------------------------- /dockerfiles/Dockerfile.ubuntu.22.04: -------------------------------------------------------------------------------- 1 | FROM ubuntu:22.04 2 | 3 | ARG RUNNERREPO="https://github.com/actions/runner" 4 | ARG RUNNERPATCH 5 | ARG SDK=8 6 | ARG ARCH 7 | 8 | ENV DEBIAN_FRONTEND=noninteractive 9 | 10 | COPY ../scripts/assets/99synaptics /etc/apt/apt.conf.d/ 11 | 12 | COPY ../scripts/assets/01-nodoc /etc/dpkg/dpkg.cfg.d/ 13 | 14 | RUN apt-get -qq update -y && \ 15 | apt-get -qq -y install --no-install-recommends \ 16 | wget git sudo curl dotnet-sdk-${SDK}.0 \ 17 | cmake make automake autoconf m4 gcc-12-base libtool && \ 18 | apt-get autoclean && \ 19 | rm -rf /var/lib/apt/lists/* 20 | 21 | RUN echo "Using SDK - $(dotnet --version)" 22 | 23 | ADD ${RUNNERPATCH} /tmp/runner.patch 24 | 25 | RUN cd /tmp && \ 26 | git clone --tags -q ${RUNNERREPO} && \ 27 | cd runner && \ 28 | git checkout $(git tag --sort=-v:refname | grep '^v[0-9]' | head -n1) && \ 29 | git apply --whitespace=nowarn /tmp/runner.patch && \ 30 | sed -i'' -e /version/s/8......\"$/8.0.100\"/ src/global.json 31 | 32 | RUN cd /tmp/runner/src && \ 33 | ./dev.sh layout Release && \ 34 | ./dev.sh package Release && \ 35 | ./dev.sh test && \ 36 | rm -rf /root/.dotnet /root/.nuget 37 | 38 | RUN useradd -c 'Action Runner' -m -s /bin/bash runner && \ 39 | usermod -L runner && \ 40 | echo 'runner ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/runner && \ 41 | chmod 440 /etc/sudoers.d/runner 42 | 43 | RUN mkdir -p /opt/runner-cache && \ 44 | tar -xf /tmp/runner/_package/*.tar.gz -C /opt/runner-cache && \ 45 | chown -R runner:runner /opt/runner-cache && \ 46 | sudo -u runner /opt/runner-cache/config.sh --version 47 | 48 | RUN rm -rf /tmp/runner /tmp/runner.patch 49 | 50 | USER runner 51 | 52 | EXPOSE 443 53 | 54 | CMD ["/bin/bash"] -------------------------------------------------------------------------------- /dockerfiles/Dockerfile.ubuntu.24.04: -------------------------------------------------------------------------------- 1 | FROM ubuntu:24.04 2 | 3 | ARG RUNNERREPO="https://github.com/actions/runner" 4 | ARG RUNNERPATCH 5 | ARG SDK=8 6 | ARG ARCH 7 | 8 | ENV DEBIAN_FRONTEND=noninteractive 9 | 10 | COPY ../scripts/assets/99synaptics /etc/apt/apt.conf.d/ 11 | 12 | COPY ../scripts/assets/01-nodoc /etc/dpkg/dpkg.cfg.d/ 13 | 14 | RUN apt-get -qq update -y && \ 15 | apt-get -qq -y install --no-install-recommends \ 16 | wget git sudo curl dotnet-sdk-${SDK}.0 \ 17 | cmake make automake autoconf m4 gcc-12-base libtool && \ 18 | apt-get autoclean && \ 19 | rm -rf /var/lib/apt/lists/* 20 | 21 | RUN echo "Using SDK - $(dotnet --version)" 22 | 23 | ADD ${RUNNERPATCH} /tmp/runner.patch 24 | 25 | RUN cd /tmp && \ 26 | git clone --tags -q ${RUNNERREPO} && \ 27 | cd runner && \ 28 | git checkout $(git tag --sort=-v:refname | grep '^v[0-9]' | head -n1) && \ 29 | git apply --whitespace=nowarn /tmp/runner.patch && \ 30 | sed -i'' -e /version/s/8......\"$/8.0.100\"/ src/global.json 31 | 32 | RUN cd /tmp/runner/src && \ 33 | ./dev.sh layout Release && \ 34 | ./dev.sh package Release && \ 35 | ./dev.sh test && \ 36 | rm -rf /root/.dotnet /root/.nuget 37 | 38 | RUN useradd -c 'Action Runner' -m -s /bin/bash runner && \ 39 | usermod -L runner && \ 40 | echo 'runner ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/runner && \ 41 | chmod 440 /etc/sudoers.d/runner 42 | 43 | RUN mkdir -p /opt/runner-cache && \ 44 | tar -xf /tmp/runner/_package/*.tar.gz -C /opt/runner-cache && \ 45 | chown -R runner:runner /opt/runner-cache && \ 46 | sudo -u runner /opt/runner-cache/config.sh --version 47 | 48 | RUN rm -rf /tmp/runner /tmp/runner.patch 49 | 50 | USER runner 51 | 52 | EXPOSE 443 53 | 54 | CMD ["/bin/bash"] -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-aws-tools.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-aws-tools.sh 4 | ## Desc: Install the AWS CLI, Session Manager plugin for the AWS CLI, and AWS SAM CLI 5 | ## Supply chain security: AWS SAM CLI - checksum validation 6 | ################################################################################ 7 | 8 | # Source the helpers for use with the script 9 | # shellcheck disable=SC1091 10 | source "$HELPER_SCRIPTS"/os.sh 11 | source "$HELPER_SCRIPTS"/install.sh 12 | 13 | # Set architecture-specific variables using a case statement for clarity 14 | case "$ARCH" in 15 | "ppc64le" | "s390x") 16 | echo "No actions defined for $ARCH architecture." 17 | exit 0 18 | ;; 19 | *) 20 | package_arch="$ARCH" 21 | ;; 22 | esac 23 | 24 | awscliv2_archive_path=$(download_with_retry "https://awscli.amazonaws.com/awscli-exe-linux-${package_arch}.zip") 25 | unzip -qq "$awscliv2_archive_path" -d /tmp 26 | /tmp/aws/install -i /usr/local/aws-cli -b /usr/local/bin 27 | 28 | smplugin_deb_path=$(download_with_retry "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/ubuntu_64bit/session-manager-plugin.deb") 29 | install_dpkgs "$smplugin_deb_path" 30 | 31 | # Download the latest aws sam cli release 32 | aws_sam_cli_archive_name="aws-sam-cli-linux-${package_arch}.zip" 33 | sam_cli_download_url=$(resolve_github_release_asset_url "aws/aws-sam-cli" "endswith(\"$aws_sam_cli_archive_name\")" "latest") 34 | aws_sam_cli_archive_path=$(download_with_retry "$sam_cli_download_url") 35 | 36 | # Supply chain security - AWS SAM CLI 37 | aws_sam_cli_hash=$(get_checksum_from_github_release "aws/aws-sam-cli" "${aws_sam_cli_archive_name}.. " "latest" "SHA256") 38 | use_checksum_comparison "$aws_sam_cli_archive_path" "$aws_sam_cli_hash" 39 | 40 | # Install the latest aws sam cli release 41 | unzip "$aws_sam_cli_archive_path" -d /tmp 42 | /tmp/install 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /images/centos/scripts/build/configure-image-data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: configure-image-data.sh 4 | ## Desc: Create a file with image data and documentation links 5 | ################################################################################ 6 | # shellcheck disable=SC2153 7 | imagedata_file="$IMAGEDATA_FILE" 8 | image_version="$IMAGE_VERSION" 9 | image_version_major=${image_version/.*/} # Extract the major version 10 | image_version_minor=$(echo "$image_version" | cut -d "." -f 2) # Extract the minor version 11 | 12 | # Determine OS name and version for CentOS 13 | # shellcheck disable=SC2002 14 | os_name=$(cat /etc/redhat-release | sed "s/ /\\\n/g") # Get OS name 15 | # shellcheck disable=SC1083 16 | os_version=$(rpm -E %{rhel}) # Get CentOS version 17 | image_label="centos-${os_version}" # Set image label 18 | 19 | # Construct documentation and release URLs 20 | github_url="https://github.com/IBM/action-runner-image-pz/blob/main/images" 21 | software_url="${github_url}/centos/toolsets/toolset-${image_version_major}${image_version_minor}.json" 22 | releaseUrl="https://github.com/actions/runner-images/releases/tag/centos${os_version}%2F${image_version_major}.${image_version_minor}" 23 | 24 | runner_image_version="$(date +%Y%m%d)" 25 | image_build_date=$(date -u +"%Y-%m-%dT%H:%M:%SZ") 26 | image_builder_id=$(cat /etc/machine-id 2>/dev/null || hostname -s 2>/dev/null) 27 | 28 | # Create the image data JSON file 29 | cat < "$imagedata_file" 30 | [ 31 | { 32 | "group": "Runner Image Provisioner", 33 | "detail": "Commit: ${BUILD_SHA}\nBuild Date: ${image_build_date}\nBuilder ID: ${image_builder_id}" 34 | }, 35 | { 36 | "group": "Operating System", 37 | "detail": "${os_name}" 38 | }, 39 | { 40 | "group": "Runner Image", 41 | "detail": "Image: ${image_label}\nVersion: ${runner_image_version}\nIncluded Software: ${software_url}\nImage Release: ${releaseUrl}" 42 | } 43 | ] 44 | EOF 45 | -------------------------------------------------------------------------------- /images/centos/scripts/build/configure-runner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | header() { 6 | TS=$(date +"%Y-%m-%dT%H:%M:%S%:z") 7 | echo "${TS} +--------------------------------------------+" 8 | echo "${TS} | $*" 9 | echo "${TS} +--------------------------------------------+" 10 | echo 11 | } 12 | 13 | msg() { 14 | # shellcheck disable=SC2046 15 | echo $(date +"%Y-%m-%dT%H:%M:%S%:z") "$*" 16 | } 17 | 18 | patch_runner() { 19 | header "Cloning repo and Patching runner" 20 | cd /tmp 21 | git clone --tags -q "${RUNNERREPO}" 22 | cd runner 23 | # shellcheck disable=SC2046 24 | git checkout $(git tag --sort=-v:refname | grep '^v[0-9]' | head -n1) 25 | git apply --whitespace=nowarn "${IMAGE_FOLDER}"/runner-sdk-8.patch 26 | sed -i'' -e '/version/s/8......"$/8.0.100"/' src/global.json 27 | } 28 | 29 | build_runner() { 30 | export DOTNET_NUGET_SIGNATURE_VERIFICATION=false 31 | header "Building runner binary" 32 | cd src 33 | 34 | msg "Running dev layout" 35 | ./dev.sh layout Release 36 | 37 | msg "Creating package" 38 | ./dev.sh package Release 39 | 40 | msg "Running tests" 41 | ./dev.sh test 42 | } 43 | 44 | install_runner() { 45 | header "Installing runner" 46 | sudo mkdir -p /opt/runner-cache 47 | sudo tar -xf /tmp/runner/_package/*.tar.gz -C /opt/runner-cache 48 | } 49 | 50 | pre_cleanup() { 51 | sudo rm -rf /tmp/runner /opt/runner-cache 52 | } 53 | 54 | post_cleanup() { 55 | sudo rm -rf "${IMAGE_FOLDER}"/runner-sdk-8.patch \ 56 | /tmp/preseed-yaml /home/ubuntu/.nuget \ 57 | /home/runner/.local/share 58 | } 59 | 60 | run() { 61 | pre_cleanup 62 | patch_runner 63 | build_runner 64 | install_runner 65 | post_cleanup 66 | } 67 | 68 | RUNNERREPO="https://github.com/actions/runner" 69 | 70 | # Parse arguments 71 | while getopts "a:" opt; do 72 | case ${opt} in 73 | a) RUNNERREPO=${OPTARG} ;; 74 | *) exit 1 ;; 75 | esac 76 | done 77 | shift $(( OPTIND - 1 )) 78 | 79 | run -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/configure-runner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | header() { 6 | TS=$(date +"%Y-%m-%dT%H:%M:%S%:z") 7 | echo "${TS} +--------------------------------------------+" 8 | echo "${TS} | $*" 9 | echo "${TS} +--------------------------------------------+" 10 | echo 11 | } 12 | 13 | msg() { 14 | # shellcheck disable=SC2046 15 | echo $(date +"%Y-%m-%dT%H:%M:%S%:z") "$*" 16 | } 17 | 18 | patch_runner() { 19 | header "Cloning repo and Patching runner" 20 | cd /tmp 21 | git clone --tags -q "${RUNNERREPO}" 22 | cd runner 23 | # shellcheck disable=SC2046 24 | git checkout $(git tag --sort=-v:refname | grep '^v[0-9]' | head -n1) 25 | git apply --whitespace=nowarn "${IMAGE_FOLDER}"/runner-sdk-8.patch 26 | sed -i'' -e '/version/s/8......"$/8.0.100"/' src/global.json 27 | } 28 | 29 | build_runner() { 30 | export DOTNET_NUGET_SIGNATURE_VERIFICATION=false 31 | header "Building runner binary" 32 | cd src 33 | 34 | msg "Running dev layout" 35 | ./dev.sh layout Release 36 | 37 | msg "Creating package" 38 | ./dev.sh package Release 39 | 40 | msg "Running tests" 41 | ./dev.sh test 42 | } 43 | 44 | install_runner() { 45 | header "Installing runner" 46 | sudo mkdir -p /opt/runner-cache 47 | sudo tar -xf /tmp/runner/_package/*.tar.gz -C /opt/runner-cache 48 | } 49 | 50 | pre_cleanup() { 51 | sudo rm -rf /tmp/runner /opt/runner-cache 52 | } 53 | 54 | post_cleanup() { 55 | sudo rm -rf "${IMAGE_FOLDER}"/runner-sdk-8.patch \ 56 | /tmp/preseed-yaml /home/ubuntu/.nuget \ 57 | /home/runner/.local/share 58 | } 59 | 60 | run() { 61 | pre_cleanup 62 | patch_runner 63 | build_runner 64 | install_runner 65 | post_cleanup 66 | } 67 | 68 | RUNNERREPO="https://github.com/actions/runner" 69 | 70 | # Parse arguments 71 | while getopts "a:" opt; do 72 | case ${opt} in 73 | a) RUNNERREPO=${OPTARG} ;; 74 | *) exit 1 ;; 75 | esac 76 | done 77 | shift $(( OPTIND - 1 )) 78 | 79 | run -------------------------------------------------------------------------------- /.github/workflows/build_main.yml: -------------------------------------------------------------------------------- 1 | name: Build runner binary (Main branch) 2 | 3 | # Controls when the workflow will run 4 | on: 5 | # Triggers the workflow on push or pull request events but only for the "main" branch 6 | push: 7 | branches: [ "main"] 8 | # Allows you to run this workflow manually from the Actions tab 9 | workflow_dispatch: 10 | 11 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 12 | jobs: 13 | # This workflow contains a single job called "build" 14 | build: 15 | # The type of runner that the job will run on 16 | runs-on: ${{ matrix.os }} 17 | strategy: 18 | matrix: 19 | include: 20 | - os: ubuntu-24.04-ppc64le 21 | runner_owner: "ppc64le-hosted" 22 | - os: ubuntu-24.04-s390x 23 | runner_owner: "s390x-hosted" 24 | # Steps represent a sequence of tasks that will be executed as part of the job 25 | steps: 26 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 27 | - uses: actions/checkout@v5 28 | 29 | # Runs a single command using the runners shell 30 | - name: Cloning repo and Patching runner 31 | run: | 32 | mkdir -p /var/tmp/imagegeneration/ 33 | cp patches/runner-main-sdk8-$(uname -m).patch /var/tmp/imagegeneration/runner-sdk-8.patch 34 | cd /tmp 35 | git clone --branch main --depth 2 https://github.com/actions/runner.git 36 | cd runner 37 | git apply --whitespace=nowarn /var/tmp/imagegeneration/runner-sdk-8.patch 38 | sed -i'' -e '/version/s/8......"$/8.0.100"/' src/global.json 39 | 40 | - name: Building runner binary 41 | run: | 42 | cd /tmp/runner/src 43 | sudo ./dev.sh layout Release 44 | sudo ./dev.sh package Release 45 | sudo ./dev.sh test 46 | 47 | - name: Installing runner 48 | run: | 49 | mkdir -p /opt/runner-cache 50 | tar -xf /tmp/runner/_package/*.tar.gz -C /opt/runner-cache 51 | /opt/runner-cache/config.sh --version 52 | -------------------------------------------------------------------------------- /.github/workflows/build_release.yml: -------------------------------------------------------------------------------- 1 | name: Build runner binary (Release) 2 | 3 | # Controls when the workflow will run 4 | on: 5 | # Triggers the workflow on push or pull request events but only for the "main" branch 6 | push: 7 | branches: [ "main"] 8 | # Allows you to run this workflow manually from the Actions tab 9 | workflow_dispatch: 10 | 11 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 12 | jobs: 13 | # This workflow contains a single job called "build" 14 | build: 15 | # The type of runner that the job will run on 16 | runs-on: ${{ matrix.os }} 17 | strategy: 18 | matrix: 19 | include: 20 | - os: ubuntu-24.04-ppc64le 21 | runner_owner: "ppc64le-hosted" 22 | - os: ubuntu-24.04-s390x 23 | runner_owner: "s390x-hosted" 24 | # Steps represent a sequence of tasks that will be executed as part of the job 25 | steps: 26 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 27 | - uses: actions/checkout@v5 28 | 29 | # Runs a single command using the runners shell 30 | - name: Cloning repo and Patching runner 31 | run: | 32 | mkdir -p /var/tmp/imagegeneration/ 33 | cp patches/runner-sdk8-$(uname -m).patch /var/tmp/imagegeneration/runner-sdk-8.patch 34 | cd /tmp 35 | git clone --tags -q https://github.com/actions/runner.git 36 | cd runner 37 | git checkout $(git tag --sort=-v:refname | grep '^v[0-9]' | head -n1) 38 | git apply --whitespace=nowarn /var/tmp/imagegeneration/runner-sdk-8.patch 39 | sed -i'' -e '/version/s/8......"$/8.0.100"/' src/global.json 40 | 41 | - name: Building runner binary 42 | run: | 43 | cd /tmp/runner/src 44 | sudo ./dev.sh layout Release 45 | sudo ./dev.sh package Release 46 | sudo ./dev.sh test 47 | 48 | - name: Installing runner 49 | run: | 50 | mkdir -p /opt/runner-cache 51 | tar -xf /tmp/runner/_package/*.tar.gz -C /opt/runner-cache 52 | /opt/runner-cache/config.sh --version 53 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/configure-dpkg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: configure-dpkg.sh 4 | ## Desc: Configure dpkg 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/etc-environment.sh 10 | source "$HELPER_SCRIPTS"/os.sh 11 | # This is the anti-frontend. It never interacts with you at all, 12 | # and makes the default answers be used for all questions. It 13 | # might mail error messages to root, but that's it; otherwise it 14 | # is completely silent and unobtrusive, a perfect frontend for 15 | # automatic installs. If you are using this front-end, and require 16 | # non-default answers to questions, you will need to pre-seed the 17 | # debconf database 18 | set_etc_environment_variable "DEBIAN_FRONTEND" "noninteractive" 19 | 20 | # dpkg can be instructed not to ask for confirmation 21 | # when replacing a configuration file (with the --force-confdef --force-confold options) 22 | cat <> /etc/apt/apt.conf.d/10dpkg-options 23 | Dpkg::Options { 24 | "--force-confdef"; 25 | "--force-confold"; 26 | } 27 | EOF 28 | 29 | # hide information about packages that are no longer required 30 | cat <> /etc/apt/apt.conf.d/10apt-autoremove 31 | APT::Get::AutomaticRemove "0"; 32 | APT::Get::HideAutoRemove "1"; 33 | EOF 34 | 35 | # Install libicu70 package for Ubuntu 24 36 | if is_ubuntu24 && [ "$ARCH" != "ppc64le" ] && [ "$ARCH" != "s390x" ]; then 37 | wget https://archive.ubuntu.com/ubuntu/pool/main/i/icu/libicu70_70.1-2_amd64.deb 38 | 39 | EXPECTED_LIBICU_SHA512="a6315482d93606e375c272718d2458870b95e4ed4b672ea8640cf7bc2d2c2f41aea13b798b1e417e1ffc472a90c6aad150d3d293aa9bddec48e39106e4042807" 40 | ACTUAL_LIBICU_SHA512="$(sha512sum "./libicu70_70.1-2_amd64.deb" | awk '{print $1}')" 41 | [ "$EXPECTED_LIBICU_SHA512" = "$ACTUAL_LIBICU_SHA512" ] || { echo "libicu checksum mismatch in configure-dpkg.sh"; exit 1;} 42 | sudo apt-get install -y ./libicu70_70.1-2_amd64.deb 43 | fi 44 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-haskell.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-haskell.sh 4 | ## Desc: Install Haskell, GHCup, Cabal and Stack 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/etc-environment.sh 10 | 11 | # Set architecture-specific variables using a case statement for clarity 12 | case "$ARCH" in 13 | "ppc64le" | "s390x") 14 | echo "No actions defined for $ARCH architecture." 15 | exit 0 16 | ;; 17 | *) 18 | ;; 19 | esac 20 | 21 | # Any nonzero value for non-interactive installation 22 | export BOOTSTRAP_HASKELL_NONINTERACTIVE=1 23 | export BOOTSTRAP_HASKELL_INSTALL_NO_STACK_HOOK=1 24 | export GHCUP_INSTALL_BASE_PREFIX=/usr/local 25 | export BOOTSTRAP_HASKELL_GHC_VERSION=0 26 | ghcup_bin=$GHCUP_INSTALL_BASE_PREFIX/.ghcup/bin 27 | set_etc_environment_variable "BOOTSTRAP_HASKELL_NONINTERACTIVE" $BOOTSTRAP_HASKELL_NONINTERACTIVE 28 | set_etc_environment_variable "GHCUP_INSTALL_BASE_PREFIX" $GHCUP_INSTALL_BASE_PREFIX 29 | 30 | # Install GHCup 31 | curl --proto '=https' --tlsv1.2 -fsSL https://get-ghcup.haskell.org | bash > /dev/null 2>&1 || true 32 | export PATH="$ghcup_bin:$PATH" 33 | prepend_etc_environment_path $ghcup_bin 34 | 35 | available_versions=$(ghcup list -t ghc -r | grep -v "prerelease" | awk '{print $2}') 36 | 37 | # Install 2 latest Haskell Major.Minor versions 38 | major_minor_versions=$(echo "$available_versions" | cut -d"." -f 1,2 | uniq | tail -n2) 39 | for major_minor_version in $major_minor_versions; do 40 | full_version=$(echo "$available_versions" | grep "$major_minor_version." | tail -n1) 41 | echo "install ghc version $full_version..." 42 | ghcup install ghc "$full_version" 43 | ghcup set ghc "$full_version" 44 | done 45 | 46 | echo "install cabal..." 47 | ghcup install cabal latest 48 | 49 | chmod -R 777 $GHCUP_INSTALL_BASE_PREFIX/.ghcup 50 | ln -s $GHCUP_INSTALL_BASE_PREFIX/.ghcup /etc/skel/.ghcup 51 | 52 | # Install the latest stable release of haskell stack 53 | curl -fsSL https://get.haskellstack.org/ | bash 54 | 55 | -------------------------------------------------------------------------------- /scripts/vm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e # Exit on any error 3 | 4 | HELPERS_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/helpers" 5 | 6 | # shellcheck disable=SC1091 7 | source "${HELPERS_DIR}"/setup_vars.sh 8 | # shellcheck disable=SC1091 9 | source "${HELPERS_DIR}"/setup_img.sh 10 | # shellcheck disable=SC1091 11 | source "${HELPERS_DIR}"/run_script.sh 12 | 13 | BUILD_PREREQS_PATH="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" 14 | 15 | msg() { 16 | # shellcheck disable=SC2046 17 | echo $(date +"%Y-%m-%dT%H:%M:%S%:z") "$*" 18 | } 19 | 20 | if [ ! -d "${BUILD_PREREQS_PATH}" ]; then 21 | msg "Check the BUILD_PREREQS_PATH specification" >&2 22 | return 3 23 | fi 24 | 25 | if [[ "$IMAGE_OS" == *"ubuntu"* ]]; then 26 | msg "Copy the apt and dpkg overrides into gha-builder - these prevent doc files from being installed" 27 | cp -r "${BUILD_PREREQS_PATH}/assets/99synaptics" "/etc/apt/apt.conf.d/99synaptics" 28 | chmod -R 0644 /etc/apt/apt.conf.d/99synaptics 29 | cp -r "${BUILD_PREREQS_PATH}/assets/01-nodoc" "/etc/dpkg/dpkg.cfg.d/01-nodoc" 30 | chmod -R 0644 /etc/dpkg/dpkg.cfg.d/01-nodoc 31 | fi 32 | 33 | msg "Copy the register-runner.sh script into gha-builder" 34 | cp -r "${BUILD_PREREQS_PATH}"/helpers/register-runner.sh "/opt/register-runner.sh" 35 | chmod -R 0755 /opt/register-runner.sh 36 | 37 | msg "Copy the /etc/rc.local - required in case podman is used" 38 | cp -r "${BUILD_PREREQS_PATH}"/assets/rc.local "/etc/rc.local" 39 | chmod -R 0755 /etc/rc.local 40 | 41 | msg "Copy the gha-service unit file into gha-builder" 42 | cp -r "${BUILD_PREREQS_PATH}"/assets/gha-runner.service "/etc/systemd/system/gha-runner.service" 43 | chmod -R 0755 /etc/systemd/system/gha-runner.service 44 | 45 | # shellcheck disable=SC2154 46 | sudo bash -c 'exec "$@"' _ "${HELPER_SCRIPTS}/setup_install.sh" "${clean_args[@]}" "${forward_args[@]}" 47 | 48 | sudo bash -c 'id -u runner >/dev/null 2>&1 || (useradd -c "Action Runner" -m -s /bin/bash runner && usermod -L runner && echo "runner ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/runner && chmod 440 /etc/sudoers.d/runner)' 49 | 50 | sudo bash -c "usermod -aG adm,users,systemd-journal,docker,lxd runner" 51 | 52 | sudo su -c "find /opt/post-generation -mindepth 1 -maxdepth 1 -type f -name '*.sh' -exec bash {} \;" -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-firefox.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-firefox.sh 4 | ## Desc: Install Firefox 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | source "$HELPER_SCRIPTS"/etc-environment.sh 11 | 12 | # Mozillateam PPA is added manually because sometimes 13 | # launchpad portal sends empty answer when trying to add it automatically 14 | 15 | REPO_URL="https://ppa.launchpadcontent.net/mozillateam/ppa/ubuntu/" 16 | GPG_FINGERPRINT="0ab215679c571d1c8325275b9bdb3d89ce49ec21" 17 | GPG_KEY="/etc/apt/trusted.gpg.d/mozillateam_ubuntu_ppa.gpg" 18 | REPO_PATH="/etc/apt/sources.list.d/mozillateam-ubuntu-ppa-focal.list" 19 | 20 | # Install Firefox 21 | curl -fsSL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x${GPG_FINGERPRINT}" | sudo gpg --dearmor -o $GPG_KEY 22 | echo "deb $REPO_URL $(lsb_release -cs) main" > $REPO_PATH 23 | 24 | update_dpkgs 25 | install_dpkgs --target-release='o=LP-PPA-mozillateam' firefox 26 | rm $REPO_PATH 27 | 28 | # Document apt source repo's 29 | echo "mozillateam $REPO_URL" >> "$HELPER_SCRIPTS"/apt-sources.txt 30 | 31 | # add to global system preferences for firefox locale en_US, because other browsers have en_US local. 32 | # Default firefox local is en_GB 33 | echo 'pref("intl.locale.requested","en_US");' >> "/usr/lib/firefox/browser/defaults/preferences/syspref.js" 34 | 35 | if [ "$ARCH" != "ppc64le" ] && [ "$ARCH" != "s390x" ]; then 36 | # Download and unpack latest release of geckodriver 37 | download_url=$(resolve_github_release_asset_url "mozilla/geckodriver" "test(\"linux64.tar.gz$\")" "latest") 38 | driver_archive_path=$(download_with_retry "$download_url") 39 | 40 | GECKODRIVER_DIR="/usr/local/share/gecko_driver" 41 | GECKODRIVER_BIN="$GECKODRIVER_DIR/geckodriver" 42 | 43 | mkdir -p $GECKODRIVER_DIR 44 | tar -xzf "$driver_archive_path" -C $GECKODRIVER_DIR 45 | 46 | chmod +x $GECKODRIVER_BIN 47 | ln -s "$GECKODRIVER_BIN" /usr/bin/ 48 | set_etc_environment_variable "GECKOWEBDRIVER" "${GECKODRIVER_DIR}" 49 | fi 50 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-microsoft-edge.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-microsoft-edge.sh 4 | ## Desc: Install Microsoft Edge and WebDriver 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | source "$HELPER_SCRIPTS"/etc-environment.sh 11 | 12 | # Set architecture-specific variables using a case statement for clarity 13 | case "$ARCH" in 14 | "ppc64le" | "s390x") 15 | echo "No actions defined for $ARCH architecture." 16 | exit 0 17 | ;; 18 | *) 19 | ;; 20 | esac 21 | 22 | REPO_URL="https://packages.microsoft.com/repos/edge" 23 | GPG_KEY="/usr/share/keyrings/microsoft-edge.gpg" 24 | REPO_PATH="/etc/apt/sources.list.d/microsoft-edge.list" 25 | 26 | wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > $GPG_KEY 27 | # Specify an arch as Microsoft repository supports armhf and arm64 as well 28 | echo "deb [arch=amd64 signed-by=$GPG_KEY] $REPO_URL stable main" > $REPO_PATH 29 | 30 | update_dpkgs 31 | install_dpkgs --no-install-recommends microsoft-edge-stable 32 | 33 | rm $GPG_KEY 34 | rm $REPO_PATH 35 | 36 | echo "microsoft-edge $REPO_URL" >> "$HELPER_SCRIPTS"/apt-sources.txt 37 | 38 | # Install Microsoft Edge Webdriver 39 | 40 | EDGEDRIVER_DIR="/usr/local/share/edge_driver" 41 | edgedriver_bin="$EDGEDRIVER_DIR/msedgedriver" 42 | 43 | mkdir -p $EDGEDRIVER_DIR 44 | 45 | edge_version=$(microsoft-edge --version | cut -d' ' -f 3) 46 | edge_version_major=$(echo "$edge_version" | cut -d'.' -f 1) 47 | 48 | edgedriver_version_url="https://msedgedriver.microsoft.com/LATEST_RELEASE_${edge_version_major}_LINUX" 49 | # Convert a resulting file to normal UTF-8 50 | edgedriver_latest_version=$(curl -fsSL "$edgedriver_version_url" | iconv -f utf-16 -t utf-8 | tr -d '\r') 51 | 52 | edgedriver_url="https://msedgedriver.microsoft.com/${edgedriver_latest_version}/edgedriver_linux64.zip" 53 | edgedriver_archive_path=$(download_with_retry "$edgedriver_url") 54 | 55 | unzip -qq "$edgedriver_archive_path" -d "$EDGEDRIVER_DIR" 56 | chmod +x $edgedriver_bin 57 | ln -s $edgedriver_bin /usr/bin 58 | 59 | set_etc_environment_variable "EDGEWEBDRIVER" "${EDGEDRIVER_DIR}" 60 | 61 | -------------------------------------------------------------------------------- /scripts/helpers/release-check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # https://gist.githubusercontent.com/electrickite/ba7e734752ee90f04587a24eb6d58b04/raw/9ee75217d17d9c6a2b04bb260d933afebd4b0afb/release-check.sh 3 | 4 | usage () { 5 | cat <&2 27 | usage >&2 28 | exit 1 29 | ;; 30 | :) 31 | echo "Option -$OPTARG requires an argument." >&2 32 | exit 1 33 | ;; 34 | esac 35 | done 36 | 37 | shift $((OPTIND-1)) 38 | 39 | if [ -z "$1" ]; then 40 | echo "No projects specified!" >&2 41 | usage >&2 42 | exit 1 43 | fi 44 | 45 | for project 46 | do 47 | url="https://api.github.com/repos/$project/releases/latest" 48 | feed="$(curl -L --silent --fail "$url")" 49 | # shellcheck disable=SC2181 50 | if [ $? -ne 0 ]; then 51 | echo "Error fetching feed!" >&2 52 | continue 53 | fi 54 | 55 | latest_release="$(echo "$feed" | jq .name | tr -d \")" 56 | # shellcheck disable=SC2181 57 | if [ $? -ne 0 ]; then 58 | echo "Error parsing feed!" >&2 59 | continue 60 | fi 61 | 62 | if [ "$latest_release" != "$last_release_version" ]; then 63 | echo "New release found for $project" 64 | echo "New release: $latest_release" 65 | echo "$latest_release" > /tmp/new_version 66 | echo "Previous release: $last_release_version" 67 | 68 | export BUILD_IMAGE=true 69 | 70 | # if [ -n "$last_release" ]; then 71 | # sed -i '' "s|$project .*|$project $latest_release|" "$last_release_path" 72 | # else 73 | # printf '%s\t%s\n' "$project" "$latest_release" >> "$last_release_path" 74 | # fi 75 | 76 | # if [ -n "$to" ]; then 77 | # from_arg="" 78 | # if [ -n "$from" ]; then 79 | # from_arg="-r $from" 80 | # fi 81 | # fi 82 | else 83 | echo "No new releases for $project" 84 | echo "Current release: $last_release_version" 85 | exit 1 86 | # shellcheck disable=SC2317 87 | export BUILD_IMAGE=false 88 | fi 89 | done 90 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/configure-apt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: configure-apt.sh 4 | ## Desc: Configure apt, install jq and apt-fast packages. 5 | ################################################################################ 6 | 7 | # shellcheck disable=SC1091 8 | source "$HELPER_SCRIPTS"/os.sh 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | # Stop and disable apt-daily upgrade services; 12 | systemctl stop apt-daily.timer 13 | systemctl disable apt-daily.timer 14 | systemctl disable apt-daily.service 15 | systemctl stop apt-daily-upgrade.timer 16 | systemctl disable apt-daily-upgrade.timer 17 | systemctl disable apt-daily-upgrade.service 18 | 19 | # Enable retry logic for apt up to 10 times 20 | echo "APT::Acquire::Retries \"10\";" > /etc/apt/apt.conf.d/80-retries 21 | 22 | # Configure apt to always assume Y 23 | echo "APT::Get::Assume-Yes \"true\";" > /etc/apt/apt.conf.d/90assumeyes 24 | 25 | # Configure apt to force IPv4 26 | echo "Acquire::ForceIPv4 \"true\";" > /etc/apt/apt.conf.d/99force-ipv4 27 | 28 | # APT understands a field called Phased-Update-Percentage which can be used to control the rollout of a new version. It is an integer between 0 and 100. 29 | # In case you have multiple systems that you want to receive the same set of updates, 30 | # you can set APT::Machine-ID to a UUID such that they all phase the same, 31 | # or set APT::Get::Never-Include-Phased-Updates or APT::Get::Always-Include-Phased-Updates to true such that APT will never/always consider phased updates. 32 | # apt-cache policy pkgname 33 | echo 'APT::Get::Always-Include-Phased-Updates "true";' > /etc/apt/apt.conf.d/99-phased-updates 34 | 35 | # Fix bad proxy and http headers settings 36 | cat <> /etc/apt/apt.conf.d/99bad_proxy 37 | Acquire::http::Pipeline-Depth 0; 38 | Acquire::http::No-Cache true; 39 | Acquire::https::Pipeline-Depth 0; 40 | Acquire::https::No-Cache true; 41 | Acquire::BrokenProxy true; 42 | EOF 43 | 44 | # Uninstall unattended-upgrades 45 | apt-get purge unattended-upgrades 46 | 47 | echo 'APT sources' 48 | if ! is_ubuntu24; then 49 | cat /etc/apt/sources.list 50 | else 51 | cat /etc/apt/sources.list.d/ubuntu.sources 52 | fi 53 | 54 | update_dpkgs 55 | # Install jq 56 | install_dpkgs jq 57 | 58 | if ! is_ubuntu24; then 59 | # Install apt-fast using quick-install.sh 60 | # https://github.com/ilikenwf/apt-fast 61 | bash -c "$(curl -fsSL https://raw.githubusercontent.com/ilikenwf/apt-fast/master/quick-install.sh)" 62 | fi 63 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-ruby.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-ruby.sh 4 | ## Desc: Install Ruby requirements and ruby gems 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/os.sh 10 | source "$HELPER_SCRIPTS"/install.sh 11 | 12 | install_dpkgs ruby-full 13 | 14 | # Install ruby gems from toolset 15 | gems_to_install=$(get_toolset_value ".rubygems[] .name") 16 | if [[ -n "$gems_to_install" ]]; then 17 | for gem in $gems_to_install; do 18 | echo "Installing gem $gem" 19 | gem install --no-document "$gem" 20 | done 21 | fi 22 | 23 | # Install Ruby requirements 24 | install_dpkgs libz-dev openssl libssl-dev 25 | 26 | # Set architecture-specific variables using a case statement for clarity 27 | # shellcheck disable=SC2153 28 | case "$ARCH" in 29 | "ppc64le" | "s390x") 30 | echo "Skipping Ruby installation from toolset on $ARCH architecture." 31 | exit 0 32 | ;; 33 | *) 34 | ;; 35 | esac 36 | 37 | echo "Install Ruby from toolset..." 38 | toolset_versions=$(get_toolset_value '.toolcache[] | select(.name | contains("Ruby")) | .versions[]') 39 | platform_version=$(get_toolset_value '.toolcache[] | select(.name | contains("Ruby")) | .platform_version') 40 | arch=$(get_toolset_value '.toolcache[] | select(.name | contains("Ruby")) | .arch') 41 | ruby_path="$AGENT_TOOLSDIRECTORY/Ruby" 42 | 43 | echo "Check if Ruby hostedtoolcache folder exist..." 44 | if [[ ! -d $ruby_path ]]; then 45 | mkdir -p "$ruby_path" 46 | fi 47 | 48 | # shellcheck disable=SC2068 49 | for toolset_version in ${toolset_versions[@]}; do 50 | download_url=$(resolve_github_release_asset_url "ruby/ruby-builder" "test(\"ruby-${toolset_version}-ubuntu-${platform_version}-${arch}.tar.gz\")" "${toolset_version}" "false" "true") 51 | package_tar_name="${download_url##*/}" 52 | ruby_version=$(echo "$package_tar_name" | cut -d'-' -f 2) 53 | ruby_version_path="$ruby_path/$ruby_version" 54 | 55 | echo "Create Ruby $ruby_version directory..." 56 | mkdir -p "$ruby_version_path" 57 | 58 | echo "Downloading tar archive $package_tar_name" 59 | package_archive_path=$(download_with_retry "$download_url") 60 | 61 | echo "Expand '$package_tar_name' to the '$ruby_version_path' folder" 62 | tar xf "$package_archive_path" -C "$ruby_version_path" 63 | 64 | complete_file_path="$ruby_version_path/x64.complete" 65 | if [[ ! -f $complete_file_path ]]; then 66 | echo "Create complete file" 67 | touch "$complete_file_path" 68 | fi 69 | done 70 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | [fork]: https://github.com/IBM/action-runner-image-pz/fork 4 | [code-of-conduct]: CODE_OF_CONDUCT.md 5 | 6 | We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great. 7 | 8 | Contributions to this project are welcome under the [Apache](LICENSE) license. 9 | 10 | Please note that this project is released with a [Contributor Code of Conduct][code-of-conduct]. By participating in this project, you agree to abide by its terms. 11 | 12 | ## Contents 13 | - [Getting Started](#getting-started) 14 | - [Submitting a pull request](#submitting-a-pull-request) 15 | - [Code style guide (coming soon!)](#code-style-guide) 16 | 17 | 18 | ## Getting started 19 | 20 | - Found a bug? [Report it here](https://github.com/IBM/action-runner-image-pz/issues/new?template=bug_report.md) 21 | - Have a feature idea? [Submit it here](https://github.com/IBM/action-runner-image-pz/issues/new?template=feature-request.md) 22 | 23 | ## Submitting a pull request 24 | 25 | 1. [Fork][fork] and clone the repository. 26 | 2. Create a new branch: `git checkout -b my-branch-name`. 27 | 3. Make your changes, ensuring that they include steps to install and validation post-install 28 | 4. Test your changes by creating and deploying the image 29 | 5. Push to your fork and [submit a pull request][pr]. 30 | 31 | ### Commit Messages 32 | 33 | __All commit messages must include a Sign-off line__ 34 | 35 | Please consider out commit message standards in order for your contribution to be merged into the main branch. 36 | 37 | #### Subject Line 38 | * __Conciseness__: Limit the subject line to around 50 characters to ensure readability in various Git tools. 39 | * __Imperative Mood__: Use the imperative mood, as if giving a command. For example, "Fix bug" instead of "Fixed bug" or "Fixes bug." 40 | * __Capitalization__: Capitalize the first letter of the subject line. 41 | * __No Period__: Do not end the subject line with a period. 42 | * __Clarity__: Summarize the core change or purpose of the commit clearly and directly. 43 | 44 | #### Body (Optional but highly recommended) 45 | * __Separate from Subject__: Leave a blank line between the subject line and the body. 46 | * __Explain "What" and "Why"__: Detail what changes were made and, more importantly, why those changes were necessary. Focus on the problem solved or the feature implemented, rather than the specific implementation details (the "how"). 47 | * __Wrap Lines__: Wrap body lines at approximately 72 characters for better readability. 48 | * __Provide Context__: Include any relevant context, such as links to issues, bug reports, or design documents, if applicable. 49 | * __Explain Side Effects__: Note any potential side effects or non-obvious consequences of the changes. 50 | 51 | 52 | -------------------------------------------------------------------------------- /scripts/docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | HELPERS_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/helpers" 4 | 5 | # shellcheck disable=SC1091 6 | source "${HELPERS_DIR}"/setup_vars.sh 7 | # shellcheck disable=SC1091 8 | source "${HELPERS_DIR}"/setup_img.sh 9 | # shellcheck disable=SC1091 10 | source "${HELPERS_DIR}"/run_script.sh 11 | 12 | # Function to ensure Docker is installed and available 13 | ensure_docker() { 14 | if ! command -v docker &> /dev/null; then 15 | echo "Docker is not installed. Attempting to install Docker..." 16 | if run_script "${HOST_INSTALLER_SCRIPT_FOLDER}/install-docker.sh" "DOCKERHUB_PULL_IMAGES" "HELPER_SCRIPTS" "INSTALLER_SCRIPT_FOLDER" "ARCH"; then 17 | echo "Docker installed successfully." 18 | else 19 | echo "Failed to install Docker. Please check your system configuration." >&2 20 | exit 1 21 | fi 22 | else 23 | echo "Docker is already installed. Version: $(docker --version)" 24 | fi 25 | } 26 | 27 | # Function to build a Docker image 28 | build_image() { 29 | local dockerfile="${HELPERS_DIR}/../../dockerfiles/Dockerfile.${IMAGE_OS}.${IMAGE_VERSION}" 30 | 31 | if [ ! -f "$dockerfile" ]; then 32 | echo "Error: Dockerfile for ${IMAGE_OS} version ${IMAGE_VERSION} not found." >&2 33 | return 1 34 | fi 35 | echo "Building Docker image for ${IMAGE_OS} version ${IMAGE_VERSION}..." 36 | docker build --no-cache -f "$dockerfile" \ 37 | --build-arg RUNNERPATCH="../patches/${PATCH_FILE}" \ 38 | --build-arg ARCH="${ARCH}" \ 39 | --tag "runner:${IMAGE_OS}.${IMAGE_VERSION}" . 40 | 41 | # shellcheck disable=SC2181 42 | if [ $? -eq 0 ]; then 43 | echo "Docker image built successfully: runner:${IMAGE_OS}.${IMAGE_VERSION}" 44 | else 45 | echo "Error: Failed to build Docker image." >&2 46 | return 1 47 | fi 48 | } 49 | 50 | # Main function to run the script 51 | run() { 52 | # Export system architecture 53 | HOST_OS_NAME=$(awk -F= '/^NAME/{print $2}' /etc/os-release | tr -d '"' | tr '[:upper:]' '[:lower:]' | awk '{print $1}') 54 | # shellcheck disable=SC2002 55 | HOST_OS_VERSION=$(cat /etc/os-release | grep -E 'VERSION_ID' | cut -d'=' -f2 | tr -d '"') 56 | HOST_INSTALLER_SCRIPT_FOLDER="${HELPERS_DIR}/../../images/${HOST_OS_NAME}/scripts/build" 57 | 58 | echo "Host OS: ${HOST_OS_NAME} ${HOST_OS_VERSION}, Architecture: ${ARCH}" 59 | echo "Target container OS: ${IMAGE_OS} ${IMAGE_VERSION}" 60 | 61 | # Ensure Docker is installed 62 | ensure_docker "$@" 63 | 64 | # Build the Docker image 65 | build_image "$@" 66 | return $? 67 | } 68 | 69 | # Execute the main function 70 | run "$@" 71 | RC=$? 72 | 73 | # Exit with the return code of the main function 74 | exit ${RC} 75 | -------------------------------------------------------------------------------- /scripts/podman.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | HELPERS_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/helpers" 4 | 5 | # shellcheck disable=SC1091 6 | source "${HELPERS_DIR}"/setup_vars.sh 7 | # shellcheck disable=SC1091 8 | source "${HELPERS_DIR}"/setup_img.sh 9 | # shellcheck disable=SC1091 10 | source "${HELPERS_DIR}"/run_script.sh 11 | 12 | # Function to ensure Podman is installed and available 13 | ensure_podman() { 14 | if ! command -v podman &> /dev/null; then 15 | echo "Podman is not installed. Attempting to install Podman..." 16 | if run_script "${HOST_INSTALLER_SCRIPT_FOLDER}/install-podman.sh" "DOCKERHUB_PULL_IMAGES" "HELPER_SCRIPTS" "INSTALLER_SCRIPT_FOLDER" "ARCH"; then 17 | echo "Podman installed successfully." 18 | else 19 | echo "Failed to install Podman. Please check your system configuration." >&2 20 | exit 1 21 | fi 22 | else 23 | echo "Podman is already installed. Version: $(podman --version)" 24 | fi 25 | } 26 | 27 | # Function to build a Podman image 28 | build_image() { 29 | local dockerfile="${HELPERS_DIR}/../../dockerfiles/Dockerfile.${IMAGE_OS}.${IMAGE_VERSION}" 30 | 31 | if [ ! -f "$dockerfile" ]; then 32 | echo "Error: Dockerfile for ${IMAGE_OS} version ${IMAGE_VERSION} not found." >&2 33 | return 1 34 | fi 35 | echo "Building Podman image for ${IMAGE_OS} version ${IMAGE_VERSION}..." 36 | podman build --no-cache -f "$dockerfile" \ 37 | --build-arg RUNNERPATCH="../patches/${PATCH_FILE}" \ 38 | --build-arg ARCH="${ARCH}" \ 39 | --tag "runner:${IMAGE_OS}.${IMAGE_VERSION}" . 40 | 41 | # shellcheck disable=SC2181 42 | if [ $? -eq 0 ]; then 43 | echo "Podman image built successfully: runner:${IMAGE_OS}.${IMAGE_VERSION}" 44 | else 45 | echo "Error: Failed to build Podman image." >&2 46 | return 1 47 | fi 48 | } 49 | 50 | # Main function to run the script 51 | run() { 52 | # Export system architecture 53 | HOST_OS_NAME=$(awk -F= '/^NAME/{print $2}' /etc/os-release | tr -d '"' | tr '[:upper:]' '[:lower:]' | awk '{print $1}') 54 | # shellcheck disable=SC2002 55 | HOST_OS_VERSION=$(cat /etc/os-release | grep -E 'VERSION_ID' | cut -d'=' -f2 | tr -d '"') 56 | HOST_INSTALLER_SCRIPT_FOLDER="${HELPERS_DIR}/../../images/${HOST_OS_NAME}/scripts/build" 57 | 58 | echo "Host OS: ${HOST_OS_NAME} ${HOST_OS_VERSION}, Architecture: ${ARCH}" 59 | echo "Target container OS: ${IMAGE_OS} ${IMAGE_VERSION}" 60 | 61 | # Ensure Podman is installed 62 | ensure_podman "$@" 63 | 64 | # Build the Podman image 65 | build_image "$@" 66 | return $? 67 | } 68 | 69 | # Execute the main function 70 | run "$@" 71 | RC=$? 72 | 73 | # Exit with the return code of the main function 74 | exit ${RC} 75 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-codeql-bundle.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-codeql-bundle.sh 4 | ## Desc: Install CodeQL CLI Bundle to the toolcache. 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | # Set architecture-specific variables using a case statement for clarity 12 | case "$ARCH" in 13 | "x86_64") 14 | package_arch="x64" 15 | bundle_platform_name="linux64" 16 | ;; 17 | "aarch64") 18 | package_arch="aarch64" 19 | bundle_platform_name="linux-aarch64" 20 | ;; 21 | *) 22 | echo "No actions defined for $ARCH architecture." 23 | exit 0 24 | ;; 25 | esac 26 | 27 | # Retrieve the latest major version of the CodeQL Action to use in the base URL for downloading the bundle. 28 | releases=$(curl -s "https://api.github.com/repos/github/codeql-action/releases") 29 | 30 | # Get the release tags starting with v[0-9] and sort them in descending order, then parse the first one to get the major version. 31 | codeql_action_latest_major_version=$(echo "$releases" | 32 | jq -r '.[].tag_name' | 33 | grep -E '^v[0-9]' | 34 | sort -nr | 35 | head -n 1 | 36 | sed -E 's/^v([0-9]+).*/\1/') 37 | if [ -z "$codeql_action_latest_major_version" ]; then 38 | echo "Error: Unable to find the latest major version of the CodeQL Action." 39 | exit 1 40 | fi 41 | 42 | # Retrieve the CLI version of the latest CodeQL bundle. 43 | base_url="$(curl -fsSL https://raw.githubusercontent.com/github/codeql-action/v"$codeql_action_latest_major_version"/src/defaults.json)" 44 | bundle_version="$(echo "$base_url" | jq -r '.cliVersion')" 45 | bundle_tag_name="codeql-bundle-v$bundle_version" 46 | 47 | echo "Downloading CodeQL bundle $bundle_version..." 48 | # Note that this is the all-platforms CodeQL bundle, to support scenarios where customers run 49 | # different operating systems within containers. 50 | codeql_archive=$(download_with_retry "https://github.com/github/codeql-action/releases/download/$bundle_tag_name/codeql-bundle-${bundle_platform_name}.tar.gz") 51 | 52 | codeql_toolcache_path="$AGENT_TOOLSDIRECTORY/CodeQL/$bundle_version/${package_arch}" 53 | mkdir -p "$codeql_toolcache_path" 54 | 55 | echo "Unpacking the downloaded CodeQL bundle archive..." 56 | tar -xzf "$codeql_archive" -C "$codeql_toolcache_path" 57 | 58 | # Touch a file to indicate to the CodeQL Action that this bundle shipped with the toolcache. This is 59 | # to support overriding the CodeQL version specified in defaults.json on GitHub Enterprise. 60 | touch "$codeql_toolcache_path/pinned-version" 61 | 62 | # Touch a file to indicate to the toolcache that setting up CodeQL is complete. 63 | touch "$codeql_toolcache_path.complete" 64 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-swift.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-swift.sh 4 | ## Desc: Install Swift 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | source "$HELPER_SCRIPTS"/etc-environment.sh 11 | 12 | # Set architecture-specific variables using a case statement for clarity 13 | case "$ARCH" in 14 | "ppc64le" | "s390x") 15 | echo "No actions defined for $ARCH architecture." 16 | exit 0 17 | ;; 18 | *) 19 | ;; 20 | esac 21 | 22 | # Install 23 | image_label="ubuntu$(lsb_release -rs)" 24 | swift_version=$(curl -fsSL "https://api.github.com/repos/apple/swift/releases/latest" | jq -r '.tag_name | match("[0-9.]+").string') 25 | swift_release_name="swift-${swift_version}-RELEASE-${image_label}" 26 | 27 | archive_url="https://swift.org/builds/swift-${swift_version}-release/${image_label//./}/swift-${swift_version}-RELEASE/${swift_release_name}.tar.gz" 28 | archive_path=$(download_with_retry "$archive_url") 29 | 30 | # Verifying PGP signature using official Swift PGP key. Referring to https://www.swift.org/install/linux/#Installation-via-Tarball 31 | # Download and import Swift PGP keys 32 | gpg --keyserver hkps://keyserver.ubuntu.com:443 \ 33 | --recv-keys \ 34 | '7463 A81A 4B2E EA1B 551F FBCF D441 C977 412B 37AD' \ 35 | '1BE1 E29A 084C B305 F397 D62A 9F59 7F4D 21A5 6D5F' \ 36 | 'A3BA FD35 56A5 9079 C068 94BD 63BC 1CFE 91D3 06C6' \ 37 | '5E4D F843 FB06 5D7F 7E24 FBA2 EF54 30F0 71E1 B235' \ 38 | '8513 444E 2DA3 6B7C 1659 AF4D 7638 F1FB 2B2B 08C4' \ 39 | 'A62A E125 BBBF BB96 A6E0 42EC 925C C1CC ED3D 1561' \ 40 | '8A74 9566 2C3C D4AE 18D9 5637 FAF6 989E 1BC1 6FEA' \ 41 | 'E813 C892 820A 6FA1 3755 B268 F167 DF1A CF9C E069' \ 42 | '52BB 7E3D E28A 71BE 22EC 05FF EF80 A866 B47A 981F' 43 | 44 | gpg --keyserver hkps://keyserver.ubuntu.com:443 --refresh-keys Swift 45 | 46 | # Download and verify signature 47 | signature_path=$(download_with_retry "${archive_url}.sig") 48 | gpg --verify "$signature_path" "$archive_path" 49 | 50 | # Remove Swift PGP public key with temporary keyring 51 | rm -rf ~/.gnupg 52 | 53 | # Extract and install swift 54 | tar xzf "$archive_path" -C /tmp 55 | 56 | SWIFT_INSTALL_ROOT="/usr/share/swift" 57 | swift_bin_root="$SWIFT_INSTALL_ROOT/usr/bin" 58 | swift_lib_root="$SWIFT_INSTALL_ROOT/usr/lib" 59 | 60 | mv "/tmp/${swift_release_name}" $SWIFT_INSTALL_ROOT 61 | mkdir -p /usr/local/lib 62 | 63 | ln -s "$swift_bin_root/swift" /usr/local/bin/swift 64 | ln -s "$swift_bin_root/swiftc" /usr/local/bin/swiftc 65 | ln -s "$swift_lib_root/libsourcekitdInProc.so" /usr/local/lib/libsourcekitdInProc.so 66 | 67 | set_etc_environment_variable "SWIFT_PATH" "${swift_bin_root}" -------------------------------------------------------------------------------- /docs/LXD_IMAGE_Used_by_GitHub_Actions_Runner.md: -------------------------------------------------------------------------------- 1 | ### **LXD Image Used by GitHub Actions Runner** 2 | 3 | This section outlines the steps to build the components required for a GitHub-hosted Actions runner using LXD. Follow these instructions to prepare the environment and execute the build process. 4 | 5 | --- 6 | 7 | ### **Prerequisites** 8 | 9 | 1. **Install LXD** 10 | - **Via Snap**: 11 | Install LXD using Snap with the following command: 12 | ```bash 13 | snap install lxd --classic 14 | ``` 15 | - **Via APT (Ubuntu)**: 16 | Alternatively, install LXD as a package available in the repository: 17 | ```bash 18 | sudo apt update 19 | sudo apt install lxd 20 | ``` 21 | 22 | 2. **Initialize LXD** 23 | - You can initialize LXD interactively or through a preseed file for automated configuration. 24 | 25 | **Interactive Initialization:** 26 | Run the command and follow the prompts to configure LXD based on your preferences: 27 | ```bash 28 | lxd init 29 | ``` 30 | 31 | **Automated Initialization:** 32 | Create a file named `lxd-preseed.yaml` with the following content to automate the initialization process: 33 | ```yaml 34 | config: {} 35 | cluster: null 36 | networks: 37 | - config: 38 | ipv4.address: auto 39 | ipv6.address: auto 40 | description: "action-runner-image-pz network" 41 | name: lxdbr0 42 | type: "" 43 | storage_pools: 44 | - config: {} 45 | description: "action-runner-image-pz storage pool" 46 | name: default 47 | driver: dir 48 | profiles: 49 | - config: {} 50 | description: "action-runner-image-pz" 51 | devices: 52 | eth0: 53 | name: eth0 54 | nictype: bridged 55 | parent: lxdbr0 56 | type: nic 57 | root: 58 | path: / 59 | pool: default 60 | type: disk 61 | name: default 62 | ``` 63 | Use the following command to apply the preseed configuration: 64 | ```bash 65 | lxd init --preseed < lxd-preseed.yaml 66 | ``` 67 | 68 | --- 69 | 70 | ### **Building the GitHub Actions Runner Image** 71 | 72 | After setting up LXD, execute the `lxd.sh` script to build the components for the GitHub Actions runner. 73 | 74 | 1. Navigate to the script's directory: 75 | ```bash 76 | cd /path/to/action-runner-image-pz/ 77 | ``` 78 | 79 | 2. Execute the build script: 80 | ``` 81 | sudo ./scripts/lxd.sh 82 | ``` 83 | The script will handle the required steps to configure the environment and build the LXD image used by the Actions runner. 84 | 85 | --- 86 | 87 | ### **Key Notes** 88 | 89 | - Ensure that the required permissions and tools are available before running the script. 90 | - For troubleshooting LXD initialization or network configurations, refer to the [official LXD documentation](https://linuxcontainers.org/lxd/docs/). 91 | -------------------------------------------------------------------------------- /images/centos/scripts/build/install-dotnetcore-sdk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-dotnetcore-sdk.sh 4 | ## Desc: Install .NET Core SDK 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/etc-environment.sh 10 | source "$HELPER_SCRIPTS"/install.sh 11 | source "$HELPER_SCRIPTS"/os.sh 12 | 13 | dotnet_versions=$(get_toolset_value '.dotnet.versions[]') 14 | dotnet_tools=$(get_toolset_value '.dotnet.tools[].name') 15 | 16 | # Disable telemetry 17 | export DOTNET_CLI_TELEMETRY_OPTOUT=1 18 | 19 | # Install dotnet dependencies 20 | # https://learn.microsoft.com/en-us/dotnet/core/install/linux-ubuntu-decision#dependencies 21 | update_dnfpkgs 22 | install_dnfpkgs ca-certificates 23 | 24 | if [[ "$ARCH" == "ppc64le" || "$ARCH" == "s390x" ]]; then 25 | echo "Installing dotnet for architecture: $ARCH" 26 | install_dnfpkgs dotnet-sdk-8.0 27 | else 28 | # Install .NET SDKs and Runtimes 29 | mkdir -p /usr/share/dotnet 30 | sdks=() 31 | # shellcheck disable=SC2068 32 | for version in ${dotnet_versions[@]}; do 33 | release_url="https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/${version}/releases.json" 34 | releases=$(cat "$(download_with_retry "$release_url")") 35 | # shellcheck disable=SC2207 36 | sdks=("${sdks[@]}" $(echo "${releases}" | jq -r '.releases[].sdk.version | select(contains("preview") or contains("rc") | not)')) 37 | # shellcheck disable=SC2207 38 | sdks=("${sdks[@]}" $(echo "${releases}" | jq -r '.releases[].sdks[]?.version | select(contains("preview") or contains("rc") | not)')) 39 | done 40 | 41 | # shellcheck disable=SC2068 42 | sorted_sdks=$(echo ${sdks[@]} | tr ' ' '\n' | sort -r | uniq -w 5) 43 | 44 | ## Download installer from dot.net 45 | DOTNET_INSTALL_SCRIPT="https://dot.net/v1/dotnet-install.sh" 46 | install_script_path=$(download_with_retry $DOTNET_INSTALL_SCRIPT) 47 | chmod +x "$install_script_path" 48 | 49 | # shellcheck disable=SC2068 50 | for sdk in ${sorted_sdks[@]}; do 51 | echo "Installing .NET SDK $sdk" 52 | $install_script_path --version "$sdk" --install-dir /usr/share/dotnet --no-path 53 | done 54 | ## Dotnet installer doesn't create symlinks to executable or modify PATH 55 | ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet 56 | fi 57 | 58 | set_etc_environment_variable DOTNET_SKIP_FIRST_TIME_EXPERIENCE 1 59 | set_etc_environment_variable DOTNET_NOLOGO 1 60 | set_etc_environment_variable DOTNET_MULTILEVEL_LOOKUP 0 61 | # shellcheck disable=SC2016 62 | prepend_etc_environment_path '$HOME/.dotnet/tools' 63 | 64 | # Install .Net tools 65 | # shellcheck disable=SC2068 66 | for dotnet_tool in ${dotnet_tools[@]}; do 67 | echo "Installing dotnet tool $dotnet_tool" 68 | dotnet tool install "$dotnet_tool" --tool-path '/etc/skel/.dotnet/tools' 69 | done -------------------------------------------------------------------------------- /images/centos/scripts/build/configure-environment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: configure-environment.sh 4 | ## Desc: Configure system and environment 5 | ################################################################################ 6 | # Source the helpers for use with the script 7 | # shellcheck disable=SC1091 8 | source "$HELPER_SCRIPTS"/os.sh 9 | source "$HELPER_SCRIPTS"/etc-environment.sh 10 | 11 | # Set ImageVersion and ImageOS env variables 12 | set_etc_environment_variable "ImageVersion" "${IMAGE_VERSION}" 13 | set_etc_environment_variable "ImageOS" "${IMAGE_OS}" 14 | 15 | # Set the ACCEPT_EULA variable to Y value to confirm your acceptance of the End-User Licensing Agreement 16 | set_etc_environment_variable "ACCEPT_EULA" "Y" 17 | 18 | # This directory is supposed to be created in $HOME and owned by user(https://github.com/actions/runner-images/issues/491) 19 | mkdir -p /etc/skel/.config/configstore 20 | # shellcheck disable=SC2016 21 | set_etc_environment_variable "XDG_CONFIG_HOME" '$HOME/.config' 22 | 23 | # Change waagent entries to use /mnt for swap file 24 | # sed -i 's/ResourceDisk.Format=n/ResourceDisk.Format=y/g' /etc/waagent.conf 25 | # sed -i 's/ResourceDisk.EnableSwap=n/ResourceDisk.EnableSwap=y/g' /etc/waagent.conf 26 | # sed -i 's/ResourceDisk.SwapSizeMB=0/ResourceDisk.SwapSizeMB=4096/g' /etc/waagent.conf 27 | 28 | # Add localhost alias to ::1 IPv6 29 | sed -i 's/::1 ip6-localhost ip6-loopback/::1 localhost ip6-localhost ip6-loopback/g' /etc/hosts 30 | 31 | # Prepare directory and env variable for toolcache 32 | AGENT_TOOLSDIRECTORY=/opt/hostedtoolcache 33 | mkdir -p $AGENT_TOOLSDIRECTORY && echo "Directory created." || echo "Directory already exists." 34 | set_etc_environment_variable "AGENT_TOOLSDIRECTORY" "${AGENT_TOOLSDIRECTORY}" 35 | set_etc_environment_variable "RUNNER_TOOL_CACHE" "${AGENT_TOOLSDIRECTORY}" 36 | chmod -R 777 $AGENT_TOOLSDIRECTORY 37 | 38 | # https://github.com/orgs/community/discussions/47563 39 | echo 'net.ipv6.conf.all.disable_ipv6=1' | tee -a /etc/sysctl.conf 40 | echo 'net.ipv6.conf.default.disable_ipv6=1' | tee -a /etc/sysctl.conf 41 | echo 'net.ipv6.conf.lo.disable_ipv6=1' | tee -a /etc/sysctl.conf 42 | 43 | # https://www.elastic.co/guide/en/elasticsearch/reference/current/vm-max-map-count.html 44 | # https://www.suse.com/support/kb/doc/?id=000016692 45 | echo 'vm.max_map_count=262144' | tee -a /etc/sysctl.conf 46 | 47 | # https://kind.sigs.k8s.io/docs/user/known-issues/#pod-errors-due-to-too-many-open-files 48 | echo 'fs.inotify.max_user_watches=655360' | tee -a /etc/sysctl.conf 49 | echo 'fs.inotify.max_user_instances=1280' | tee -a /etc/sysctl.conf 50 | 51 | # https://github.com/actions/runner-images/issues/9491 52 | echo 'vm.mmap_rnd_bits=28' | tee -a /etc/sysctl.conf 53 | 54 | # https://github.com/actions/runner-images/pull/7860 55 | netfilter_rule='/etc/udev/rules.d/50-netfilter.rules' 56 | rules_directory="$(dirname "${netfilter_rule}")" 57 | mkdir -p "$rules_directory" 58 | touch $netfilter_rule 59 | echo 'ACTION=="add", SUBSYSTEM=="module", KERNEL=="nf_conntrack", RUN+="/usr/sbin/sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1"' | tee -a $netfilter_rule 60 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-dotnetcore-sdk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-dotnetcore-sdk.sh 4 | ## Desc: Install .NET Core SDK 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/etc-environment.sh 10 | source "$HELPER_SCRIPTS"/install.sh 11 | source "$HELPER_SCRIPTS"/os.sh 12 | 13 | dotnet_versions=$(get_toolset_value '.dotnet.versions[]') 14 | dotnet_tools=$(get_toolset_value '.dotnet.tools[].name') 15 | 16 | # Disable telemetry 17 | export DOTNET_CLI_TELEMETRY_OPTOUT=1 18 | 19 | # Install dotnet dependencies 20 | # https://learn.microsoft.com/en-us/dotnet/core/install/linux-ubuntu-decision#dependencies 21 | update_dpkgs 22 | install_dpkgs --no-install-recommends \ 23 | ca-certificates \ 24 | libc6 \ 25 | libgcc-s1 \ 26 | libgssapi-krb5-2 \ 27 | liblttng-ust1 \ 28 | libssl3 \ 29 | libstdc++6 \ 30 | zlib1g 31 | 32 | if is_ubuntu22; then 33 | install_dpkgs --no-install-recommends libicu70 34 | fi 35 | 36 | if is_ubuntu24; then 37 | install_dpkgs --no-install-recommends libicu74 38 | fi 39 | 40 | if [[ "$ARCH" == "ppc64le" || "$ARCH" == "s390x" ]]; then 41 | echo "Installing dotnet for architecture: $ARCH" 42 | install_dpkgs dotnet-sdk-8.0 43 | else 44 | # Install .NET SDKs and Runtimes 45 | mkdir -p /usr/share/dotnet 46 | sdks=() 47 | # shellcheck disable=SC2068 48 | for version in ${dotnet_versions[@]}; do 49 | release_url="https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/${version}/releases.json" 50 | releases=$(cat "$(download_with_retry "$release_url")") 51 | # shellcheck disable=SC2207 52 | sdks=("${sdks[@]}" $(echo "${releases}" | jq -r '.releases[].sdk.version | select(contains("preview") or contains("rc") | not)')) 53 | # shellcheck disable=SC2207 54 | sdks=("${sdks[@]}" $(echo "${releases}" | jq -r '.releases[].sdks[]?.version | select(contains("preview") or contains("rc") | not)')) 55 | done 56 | 57 | # shellcheck disable=SC2068 58 | sorted_sdks=$(echo ${sdks[@]} | tr ' ' '\n' | sort -r | uniq -w 5) 59 | 60 | ## Download installer from dot.net 61 | DOTNET_INSTALL_SCRIPT="https://dot.net/v1/dotnet-install.sh" 62 | install_script_path=$(download_with_retry $DOTNET_INSTALL_SCRIPT) 63 | chmod +x "$install_script_path" 64 | 65 | # shellcheck disable=SC2068 66 | for sdk in ${sorted_sdks[@]}; do 67 | echo "Installing .NET SDK $sdk" 68 | $install_script_path --version "$sdk" --install-dir /usr/share/dotnet --no-path 69 | done 70 | ## Dotnet installer doesn't create symlinks to executable or modify PATH 71 | ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet 72 | fi 73 | 74 | set_etc_environment_variable DOTNET_SKIP_FIRST_TIME_EXPERIENCE 1 75 | set_etc_environment_variable DOTNET_NOLOGO 1 76 | set_etc_environment_variable DOTNET_MULTILEVEL_LOOKUP 0 77 | # shellcheck disable=SC2016 78 | prepend_etc_environment_path '$HOME/.dotnet/tools' 79 | 80 | # Install .Net tools 81 | # shellcheck disable=SC2068 82 | for dotnet_tool in ${dotnet_tools[@]}; do 83 | echo "Installing dotnet tool $dotnet_tool" 84 | dotnet tool install "$dotnet_tool" --tool-path '/etc/skel/.dotnet/tools' 85 | done 86 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-kubernetes-tools.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-kubernetes-tools.sh 4 | ## Desc: Installs kubectl, helm, kustomize 5 | ## Supply chain security: KIND, minikube - checksum validation 6 | ################################################################################ 7 | 8 | # Source the helpers for use with the script 9 | # shellcheck disable=SC1091 10 | source "$HELPER_SCRIPTS"/install.sh 11 | 12 | # Set architecture-specific variables using a case statement for clarity 13 | case "$ARCH" in 14 | "x86_64") 15 | package_arch="amd64" 16 | ;; 17 | "ppc64le" | "s390x" | *) 18 | package_arch="$ARCH" 19 | ;; 20 | esac 21 | 22 | if [[ "$ARCH" == "ppc64le" || "$ARCH" == "s390x" ]]; then 23 | export version="latest" 24 | install_dpkgs golang 25 | sudo go install sigs.k8s.io/kind@$version # v0.22.0 26 | # shellcheck disable=SC2046 27 | sudo cp $(sudo go env GOPATH)/bin/kind /usr/local/bin/ 28 | kind version 29 | else 30 | # Download KIND 31 | kind_url=$(resolve_github_release_asset_url "kubernetes-sigs/kind" "endswith(\"kind-linux-${package_arch}\")" "latest") 32 | kind_binary_path=$(download_with_retry "${kind_url}") 33 | 34 | # Supply chain security - KIND 35 | kind_external_hash=$(get_checksum_from_url "${kind_url}.sha256sum" "kind-linux-${package_arch}" "SHA256") 36 | use_checksum_comparison "${kind_binary_path}" "${kind_external_hash}" 37 | 38 | # Install KIND 39 | install "${kind_binary_path}" /usr/local/bin/kind 40 | fi 41 | 42 | # Install kubectl 43 | 44 | # Ensure keyrings directory exists only if it doesn't already 45 | [ -d /etc/apt/keyrings ] || sudo mkdir -p -m 755 /etc/apt/keyrings 46 | 47 | kubectl_minor_version=$(curl -fsSL --retry 5 --retry-delay 10 "https://dl.k8s.io/release/stable.txt" | cut -d'.' -f1,2 ) 48 | 49 | # Download and validate GPG key 50 | key_url="https://pkgs.k8s.io/core:/stable:/$kubectl_minor_version/deb/Release.key" 51 | if curl -fsSL --retry 5 --retry-delay 10 -A "Mozilla/5.0" "$key_url" | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg; then 52 | echo "Key downloaded and stored successfully." 53 | else 54 | echo "Failed to download valid GPG key from: $key_url" 55 | exit 1 56 | fi 57 | 58 | echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/'"$kubectl_minor_version"'/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list 59 | update_dpkgs 60 | install_dpkgs kubectl 61 | rm -f /etc/apt/sources.list.d/kubernetes.list 62 | 63 | # Install Helm 64 | curl -fsSL https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash 65 | 66 | 67 | # Download and install minikube 68 | minikube_version="latest" 69 | minikube_binary_path=$(download_with_retry "https://storage.googleapis.com/minikube/releases/${minikube_version}/minikube-linux-${package_arch}") 70 | 71 | # Supply chain security - Minikube 72 | minikube_hash=$(get_checksum_from_github_release "kubernetes/minikube" "linux-${package_arch}" "${minikube_version}" "SHA256") 73 | use_checksum_comparison "${minikube_binary_path}" "${minikube_hash}" 74 | 75 | install "${minikube_binary_path}" /usr/local/bin/minikube 76 | 77 | # Install kustomize 78 | download_url="https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" 79 | curl -fsSL "$download_url" | bash 80 | mv kustomize /usr/local/bin 81 | -------------------------------------------------------------------------------- /images/centos/scripts/helpers/etc-environment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: etc-environment.sh 4 | ## Desc: Helper functions for source and modify /etc/environment 5 | ################################################################################ 6 | 7 | # NB: sed expression use '%' as a delimiter in order to simplify handling 8 | # values containing slashes (i.e. directory path) 9 | # The values containing '%' will break the functions 10 | 11 | get_etc_environment_variable() { 12 | local variable_name=$1 13 | 14 | # remove `variable_name=` and possible quotes from the line 15 | grep "^${variable_name}=" /etc/environment | sed -E "s%^${variable_name}=\"?([^\"]+)\"?.*$%\1%" 16 | } 17 | 18 | add_etc_environment_variable() { 19 | local variable_name=$1 20 | local variable_value=$2 21 | 22 | echo "${variable_name}=${variable_value}" | sudo tee -a /etc/environment 23 | } 24 | 25 | replace_etc_environment_variable() { 26 | local variable_name=$1 27 | local variable_value=$2 28 | 29 | # modify /etc/environemnt in place by replacing a string that begins with variable_name 30 | sudo sed -i -e "s%^${variable_name}=.*$%${variable_name}=${variable_value}%" /etc/environment 31 | } 32 | 33 | set_etc_environment_variable() { 34 | local variable_name=$1 35 | local variable_value=$2 36 | 37 | if grep "^${variable_name}=" /etc/environment > /dev/null; then 38 | replace_etc_environment_variable "$variable_name" "$variable_value" 39 | else 40 | add_etc_environment_variable "$variable_name" "$variable_value" 41 | fi 42 | } 43 | 44 | prepend_etc_environment_variable() { 45 | local variable_name=$1 46 | local element=$2 47 | 48 | # TODO: handle the case if the variable does not exist 49 | existing_value=$(get_etc_environment_variable "${variable_name}") 50 | set_etc_environment_variable "${variable_name}" "${element}:${existing_value}" 51 | } 52 | 53 | append_etc_environment_variable() { 54 | local variable_name=$1 55 | local element=$2 56 | 57 | # TODO: handle the case if the variable does not exist 58 | existing_value=$(get_etc_environment_variable "${variable_name}") 59 | set_etc_environment_variable "${variable_name}" "${existing_value}:${element}" 60 | } 61 | 62 | prepend_etc_environment_path() { 63 | local element=$1 64 | 65 | prepend_etc_environment_variable PATH "${element}" 66 | } 67 | 68 | append_etc_environment_path() { 69 | local element=$1 70 | 71 | append_etc_environment_variable PATH "${element}" 72 | } 73 | 74 | # Process /etc/environment as if it were shell script with `export VAR=...` expressions 75 | # The PATH variable is handled specially in order to do not override the existing PATH 76 | # variable. The value of PATH variable read from /etc/environment is added to the end 77 | # of value of the exiting PATH variable exactly as it would happen with real PAM app read 78 | # /etc/environment 79 | # 80 | # TODO: there might be the others variables to be processed in the same way as "PATH" variable 81 | # ie MANPATH, INFOPATH, LD_*, etc. In the current implementation the values from /etc/evironments 82 | # replace the values of the current environment 83 | reload_etc_environment() { 84 | # add `export ` to every variable of /etc/environemnt except PATH and eval the result shell script 85 | # shellcheck disable=SC2046 86 | eval $(grep -v '^PATH=' /etc/environment | sed -e 's%^%export %') 87 | # handle PATH specially 88 | etc_path=$(get_etc_environment_variable PATH) 89 | export PATH="$PATH:$etc_path" 90 | } 91 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/helpers/etc-environment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: etc-environment.sh 4 | ## Desc: Helper functions for source and modify /etc/environment 5 | ################################################################################ 6 | 7 | # NB: sed expression use '%' as a delimiter in order to simplify handling 8 | # values containing slashes (i.e. directory path) 9 | # The values containing '%' will break the functions 10 | 11 | get_etc_environment_variable() { 12 | local variable_name=$1 13 | 14 | # remove `variable_name=` and possible quotes from the line 15 | grep "^${variable_name}=" /etc/environment | sed -E "s%^${variable_name}=\"?([^\"]+)\"?.*$%\1%" 16 | } 17 | 18 | add_etc_environment_variable() { 19 | local variable_name=$1 20 | local variable_value=$2 21 | 22 | echo "${variable_name}=${variable_value}" | sudo tee -a /etc/environment 23 | } 24 | 25 | replace_etc_environment_variable() { 26 | local variable_name=$1 27 | local variable_value=$2 28 | 29 | # modify /etc/environemnt in place by replacing a string that begins with variable_name 30 | sudo sed -i -e "s%^${variable_name}=.*$%${variable_name}=${variable_value}%" /etc/environment 31 | } 32 | 33 | set_etc_environment_variable() { 34 | local variable_name=$1 35 | local variable_value=$2 36 | 37 | if grep "^${variable_name}=" /etc/environment > /dev/null; then 38 | replace_etc_environment_variable "$variable_name" "$variable_value" 39 | else 40 | add_etc_environment_variable "$variable_name" "$variable_value" 41 | fi 42 | } 43 | 44 | prepend_etc_environment_variable() { 45 | local variable_name=$1 46 | local element=$2 47 | 48 | # TODO: handle the case if the variable does not exist 49 | existing_value=$(get_etc_environment_variable "${variable_name}") 50 | set_etc_environment_variable "${variable_name}" "${element}:${existing_value}" 51 | } 52 | 53 | append_etc_environment_variable() { 54 | local variable_name=$1 55 | local element=$2 56 | 57 | # TODO: handle the case if the variable does not exist 58 | existing_value=$(get_etc_environment_variable "${variable_name}") 59 | set_etc_environment_variable "${variable_name}" "${existing_value}:${element}" 60 | } 61 | 62 | prepend_etc_environment_path() { 63 | local element=$1 64 | 65 | prepend_etc_environment_variable PATH "${element}" 66 | } 67 | 68 | append_etc_environment_path() { 69 | local element=$1 70 | 71 | append_etc_environment_variable PATH "${element}" 72 | } 73 | 74 | # Process /etc/environment as if it were shell script with `export VAR=...` expressions 75 | # The PATH variable is handled specially in order to do not override the existing PATH 76 | # variable. The value of PATH variable read from /etc/environment is added to the end 77 | # of value of the exiting PATH variable exactly as it would happen with real PAM app read 78 | # /etc/environment 79 | # 80 | # TODO: there might be the others variables to be processed in the same way as "PATH" variable 81 | # ie MANPATH, INFOPATH, LD_*, etc. In the current implementation the values from /etc/evironments 82 | # replace the values of the current environment 83 | reload_etc_environment() { 84 | # add `export ` to every variable of /etc/environemnt except PATH and eval the result shell script 85 | # shellcheck disable=SC2046 86 | eval $(grep -v '^PATH=' /etc/environment | sed -e 's%^%export %') 87 | # handle PATH specially 88 | etc_path=$(get_etc_environment_variable PATH) 89 | export PATH="$PATH:$etc_path" 90 | } 91 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-php.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-php.sh 4 | ## Desc: Install php 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/etc-environment.sh 10 | source "$HELPER_SCRIPTS"/os.sh 11 | source "$HELPER_SCRIPTS"/install.sh 12 | 13 | # Install PHP 14 | php_versions=$(get_toolset_value '.php.versions[]') 15 | 16 | for version in $php_versions; do 17 | echo "Installing PHP $version" 18 | install_dpkgs --no-install-recommends \ 19 | php"$version" \ 20 | php"$version"-amqp \ 21 | php"$version"-apcu \ 22 | php"$version"-bcmath \ 23 | php"$version"-bz2 \ 24 | php"$version"-cgi \ 25 | php"$version"-cli \ 26 | php"$version"-common \ 27 | php"$version"-curl \ 28 | php"$version"-dba \ 29 | php"$version"-dev \ 30 | php"$version"-enchant \ 31 | php"$version"-fpm \ 32 | php"$version"-gd \ 33 | php"$version"-gmp \ 34 | php"$version"-igbinary \ 35 | php"$version"-imagick \ 36 | php"$version"-imap \ 37 | php"$version"-interbase \ 38 | php"$version"-intl \ 39 | php"$version"-ldap \ 40 | php"$version"-mbstring \ 41 | php"$version"-memcache \ 42 | php"$version"-memcached \ 43 | php"$version"-mongodb \ 44 | php"$version"-mysql \ 45 | php"$version"-odbc \ 46 | php"$version"-opcache \ 47 | php"$version"-pgsql \ 48 | php"$version"-phpdbg \ 49 | php"$version"-pspell \ 50 | php"$version"-readline \ 51 | php"$version"-redis \ 52 | php"$version"-snmp \ 53 | php"$version"-soap \ 54 | php"$version"-sqlite3 \ 55 | php"$version"-sybase \ 56 | php"$version"-tidy \ 57 | php"$version"-xdebug \ 58 | php"$version"-xml \ 59 | php"$version"-xsl \ 60 | php"$version"-yaml \ 61 | php"$version"-zip \ 62 | php"$version"-zmq 63 | 64 | install_dpkgs --no-install-recommends php"$version"-pcov 65 | 66 | # Disable PCOV, as Xdebug is enabled by default 67 | # https://github.com/krakjoe/pcov#interoperability 68 | phpdismod -v "$version" pcov 69 | 70 | if [[ $version == "7.2" || $version == "7.3" || $version == "7.4" ]]; then 71 | install_dpkgs --no-install-recommends php"$version"-recode 72 | fi 73 | 74 | if [[ $version != "8.0" && $version != "8.1" && $version != "8.2" && $version != "8.3" ]]; then 75 | install_dpkgs --no-install-recommends php"$version"-xmlrpc php"$version"-json 76 | fi 77 | done 78 | 79 | install_dpkgs --no-install-recommends php-pear 80 | 81 | install_dpkgs --no-install-recommends snmp 82 | 83 | # Install composer 84 | php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" 85 | php -r "if (hash_file('sha384', 'composer-setup.php') === file_get_contents('https://composer.github.io/installer.sig')) { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" 86 | php composer-setup.php 87 | sudo mv composer.phar /usr/bin/composer 88 | php -r "unlink('composer-setup.php');" 89 | 90 | # Add composer bin folder to path 91 | # shellcheck disable=SC2016 92 | prepend_etc_environment_path '$HOME/.config/composer/vendor/bin' 93 | 94 | #Create composer folder for user to preserve folder permissions 95 | mkdir -p /etc/skel/.composer 96 | 97 | # Install phpunit (for PHP) 98 | wget -q -O phpunit https://phar.phpunit.de/phpunit-8.phar 99 | install phpunit /usr/local/bin/phpunit 100 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/configure-environment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: configure-environment.sh 4 | ## Desc: Configure system and environment 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/os.sh 10 | source "$HELPER_SCRIPTS"/etc-environment.sh 11 | 12 | # Set ImageVersion and ImageOS env variables 13 | set_etc_environment_variable "ImageVersion" "${IMAGE_VERSION}" 14 | set_etc_environment_variable "ImageOS" "${IMAGE_OS}" 15 | 16 | # Set the ACCEPT_EULA variable to Y value to confirm your acceptance of the End-User Licensing Agreement 17 | set_etc_environment_variable "ACCEPT_EULA" "Y" 18 | 19 | # This directory is supposed to be created in $HOME and owned by user(https://github.com/actions/runner-images/issues/491) 20 | mkdir -p /etc/skel/.config/configstore 21 | # shellcheck disable=SC2016 22 | set_etc_environment_variable "XDG_CONFIG_HOME" '$HOME/.config' 23 | 24 | # Change waagent entries to use /mnt for swap file 25 | if [[ -f /etc/waagent.conf ]]; then 26 | sed -i 's/ResourceDisk.Format=n/ResourceDisk.Format=y/g' /etc/waagent.conf 27 | sed -i 's/ResourceDisk.EnableSwap=n/ResourceDisk.EnableSwap=y/g' /etc/waagent.conf 28 | sed -i 's/ResourceDisk.SwapSizeMB=0/ResourceDisk.SwapSizeMB=4096/g' /etc/waagent.conf 29 | fi 30 | 31 | # Add localhost alias to ::1 IPv6 32 | sed -i 's/::1 ip6-localhost ip6-loopback/::1 localhost ip6-localhost ip6-loopback/g' /etc/hosts 33 | 34 | # Prepare directory and env variable for toolcache 35 | AGENT_TOOLSDIRECTORY=/opt/hostedtoolcache 36 | mkdir $AGENT_TOOLSDIRECTORY 37 | set_etc_environment_variable "AGENT_TOOLSDIRECTORY" "${AGENT_TOOLSDIRECTORY}" 38 | set_etc_environment_variable "RUNNER_TOOL_CACHE" "${AGENT_TOOLSDIRECTORY}" 39 | chmod -R 777 $AGENT_TOOLSDIRECTORY 40 | 41 | # https://www.elastic.co/guide/en/elasticsearch/reference/current/vm-max-map-count.html 42 | # https://www.suse.com/support/kb/doc/?id=000016692 43 | echo 'vm.max_map_count=262144' | tee -a /etc/sysctl.conf 44 | 45 | # https://kind.sigs.k8s.io/docs/user/known-issues/#pod-errors-due-to-too-many-open-files 46 | echo 'fs.inotify.max_user_watches=655360' | tee -a /etc/sysctl.conf 47 | echo 'fs.inotify.max_user_instances=1280' | tee -a /etc/sysctl.conf 48 | 49 | # https://github.com/actions/runner-images/issues/9491 50 | echo 'vm.mmap_rnd_bits=28' | tee -a /etc/sysctl.conf 51 | 52 | # https://github.com/actions/runner-images/pull/7860 53 | netfilter_rule='/etc/udev/rules.d/50-netfilter.rules' 54 | rules_directory="$(dirname "${netfilter_rule}")" 55 | mkdir -p "$rules_directory" 56 | touch $netfilter_rule 57 | echo 'ACTION=="add", SUBSYSTEM=="module", KERNEL=="nf_conntrack", RUN+="/usr/sbin/sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1"' | tee -a $netfilter_rule 58 | 59 | # Disable motd updates metadata 60 | if [[ -f /etc/default/motd-news ]]; then 61 | sed -i 's/ENABLED=1/ENABLED=0/g' /etc/default/motd-news 62 | fi 63 | # Remove fwupd if installed. We're running on VMs in Azure and the fwupd package is not needed. 64 | # Leaving it enable means periodic refreshes show in network traffic and firewall logs 65 | # Check if fwupd-refresh.timer exists in systemd 66 | if systemctl list-unit-files fwupd-refresh.timer &>/dev/null; then 67 | echo "Masking fwupd-refresh.timer..." 68 | systemctl mask fwupd-refresh.timer 69 | fi 70 | 71 | # This is a legacy check, leaving for earlier versions of Ubuntu 72 | # If fwupd config still exists, disable the motd updates 73 | if [[ -f "/etc/fwupd/daemon.conf" ]]; then 74 | sed -i 's/UpdateMotd=true/UpdateMotd=false/g' /etc/fwupd/daemon.conf 75 | fi 76 | 77 | # Disable to load providers 78 | # https://github.com/microsoft/azure-pipelines-agent/issues/3834 79 | if is_ubuntu22; then 80 | sed -i 's/openssl_conf = openssl_init/#openssl_conf = openssl_init/g' /etc/ssl/openssl.cnf 81 | fi 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GitHub Action Runner Image for IBM Power (ppc64le) and IBM Z (s390x) 2 | 3 | Github Actions LXD Image Builder 4 | 5 | Formerly known as GapLib, this repo is a robust collection of setup scripts for configuring custom GitHub Actions runners. These scripts are designed to seamlessly adapt to updates in `actions/runner`, ensuring compatibility and optimal performance across diverse environments, including **VM (host machine)**, **LXD**, **Docker**, and **Podman**. 6 | 7 | This repository also includes source code to create VM images for GitHub-hosted runners widely used in Actions workflows. This image supports multiple operating systems and architectures, providing a versatile and scalable solution to meet diverse project requirements. 8 | 9 | 10 | ## **Table of Contents** 11 | 12 | - [Overview](#overview) 13 | - [Supported Environments](#supported-environments) 14 | - [Supported Architectures](#supported-architectures) 15 | - [Supported Operating Systems](#supported-operating-systems) 16 | - [Scripts](#scripts) 17 | - [run.sh](#runsh) 18 | - [Key Features](#key-features) 19 | - [Usage](#usage) 20 | - [Setup Options](#setup-options) 21 | - [Main Menu](#main-menu) 22 | - [OS and Version Selection](#os-and-version-selection) 23 | - [Minimal or Complete Setup](#minimal-or-complete-setup) 24 | - [Unsupported Architectures](#unsupported-architectures) 25 | - [Requirements](#requirements) 26 | - [Contributing](#contributing) 27 | 28 | --- 29 | 30 | ## **Overview** 31 | 32 | ### **Supported Environments** 33 | 34 | This runner image supports multiple environments on IBM hardware for seamless runner setup: 35 | 36 | - **VM (host machine)**: Direct setup on virtual or host machines. 37 | - **LXD**: Lightweight container-based virtualization. 38 | - **Docker**: Industry-standard containerization platform. 39 | - **Podman**: Docker-compatible, daemonless container management. 40 | 41 | ### **Supported Architectures** 42 | 43 | - **ppc64le** 44 | - **s390x** 45 | - **x86_64** 46 | 47 | ### **Supported Operating Systems** 48 | 49 | - **Ubuntu**: Versions 22.04, and 24.04. 50 | - **CentOS**: Version 9. 51 | 52 | --- 53 | 54 | ## **Scripts** 55 | 56 | ### **run.sh** 57 | 58 | `run.sh` is the primary script for setting up GitHub Actions runners. It provides an interactive, menu-driven interface for selecting environments, operating systems, versions, and setup types. 59 | 60 | ### **Key Features** 61 | 62 | - **Interactive Menu**: Guides users through setup options (VM, LXD, Docker, or Podman). 63 | - **Architecture Detection**: Ensures compatibility with supported architectures. 64 | - **Custom OS and Version Selection**: Allows users to tailor setup to specific environments. 65 | - **Setup Type Options**: Supports **Minimal** (basic setup) and **Complete** (full setup) configurations. 66 | 67 | --- 68 | 69 | ## **Usage** 70 | 71 | 1. Clone the repository 72 | 73 | 74 | 2. Execute the setup script: 75 | 76 | ```bash 77 | bash run.sh 78 | 79 | ``` 80 | 81 | 3. Follow the prompts to: 82 | - Select your environment (**VM**, **LXD**, **Docker**, or **Podman**). 83 | - Choose your OS and version. 84 | - Specify the setup type (**Minimal** or **Complete**). 85 | 86 | --- 87 | 88 | ## **Setup Options** 89 | 90 | ### **Main Menu** 91 | 92 | The script provides the following main options: 93 | 94 | ``` 95 | 1. VM (host machine) 96 | 2. LXD 97 | 3. Docker 98 | 4. Podman 99 | 5. Exit 100 | 101 | ``` 102 | 103 | Select an option to proceed with the setup. 104 | 105 | ### **OS and Version Selection** 106 | 107 | Choose your preferred operating system and version (Ubuntu or CentOS). If a version is not specified, the script will prompt you for a selection. 108 | 109 | ### **Minimal or Complete Setup** 110 | 111 | - **Minimal Setup**: Installs only the essential components. 112 | - **Complete Setup**: Performs a full installation with additional configurations. 113 | 114 | ### **Unsupported Architectures** 115 | 116 | If the script encounters an unsupported architecture, it will provide these options: 117 | 118 | ``` 119 | 1. Return to the previous step 120 | 2. Exit 121 | 122 | ``` 123 | 124 | --- 125 | 126 | ## **Requirements** 127 | 128 | - **Bash Shell**: Required to execute the scripts. 129 | - **Sudo Privileges**: Necessary for certain setup tasks depending on the environment. 130 | 131 | --- 132 | 133 | # Archived repo 134 | 135 | This repo was previously hosted here: https://github.com/ppc64le/gaplib 136 | 137 | 138 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-google-chrome.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-google-chrome.sh 4 | ## Desc: Install google-chrome, chromedriver and chromium 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | source "$HELPER_SCRIPTS"/etc-environment.sh 11 | 12 | # Set architecture-specific variables using a case statement for clarity 13 | case "$ARCH" in 14 | "ppc64le" | "s390x") 15 | echo "No actions defined for $ARCH architecture." 16 | exit 0 17 | ;; 18 | *) 19 | ;; 20 | esac 21 | 22 | get_chromium_revision() { 23 | local chrome_revision=$1 24 | 25 | # Take the first part of the revision variable to search not only for a specific version, 26 | # but also for similar ones, so that we can get a previous one if the required revision is not found 27 | chrome_revision_prefix=${chrome_revision:0:${#chrome_revision}/2+1} 28 | SEARCH_URL="https://www.googleapis.com/storage/v1/b/chromium-browser-snapshots/o?delimiter=/&prefix=Linux_x64" 29 | # Revision can include a hash instead of a number. Need to filter it out https://github.com/actions/runner-images/issues/5256 30 | revisions_available=$(curl -s "$SEARCH_URL/${chrome_revision_prefix}" | jq -r '.prefixes[]' | grep -E "Linux_x64\/[0-9]+\/"| cut -d "/" -f 2 | sort --version-sort) 31 | 32 | # If required Chromium revision is not found in the list 33 | # we should have to decrement the revision number until we find one. 34 | # This is mentioned in the documentation we use for this installation: 35 | # https://www.chromium.org/getting-involved/download-chromium 36 | latest_valid_revision=$(echo "$revisions_available" | cut -f 1 -d " ") 37 | for revision in $revisions_available; do 38 | if [ "$chrome_revision" -lt "$revision" ]; then 39 | break 40 | fi 41 | 42 | latest_valid_revision=$revision 43 | done 44 | 45 | echo "$latest_valid_revision" 46 | } 47 | 48 | # Download and install Google Chrome 49 | CHROME_DEB_URL="https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb" 50 | chrome_deb_path=$(download_with_retry "$CHROME_DEB_URL") 51 | install_dpkgs "$chrome_deb_path" -f 52 | set_etc_environment_variable "CHROME_BIN" "/usr/bin/google-chrome" 53 | 54 | # Remove Google Chrome repo 55 | rm -f /etc/cron.daily/google-chrome /etc/apt/sources.list.d/google-chrome.list /etc/apt/sources.list.d/google-chrome.list.save 56 | 57 | # Parse Google Chrome version 58 | full_chrome_version=$(google-chrome --product-version) 59 | chrome_version=${full_chrome_version%.*} 60 | echo "Chrome version is $full_chrome_version" 61 | 62 | # Get chrome versions information 63 | CHROME_PLATFORM="linux64" 64 | CHROME_VERSIONS_URL="https://googlechromelabs.github.io/chrome-for-testing/latest-patch-versions-per-build-with-downloads.json" 65 | chrome_versions_json=$(curl -fsSL "${CHROME_VERSIONS_URL}") 66 | 67 | # Download and unpack the latest release of chromedriver 68 | chromedriver_version=$(echo "${chrome_versions_json}" | jq -r '.builds["'"$chrome_version"'"].version') 69 | chromedriver_url=$(echo "${chrome_versions_json}" | jq -r '.builds["'"$chrome_version"'"].downloads.chromedriver[] | select(.platform=="'"${CHROME_PLATFORM}"'").url') 70 | CHROMEDRIVER_DIR="/usr/local/share/chromedriver-linux64" 71 | chromedriver_bin="$CHROMEDRIVER_DIR/chromedriver" 72 | 73 | echo "Installing chromedriver version $chromedriver_version" 74 | driver_archive_path=$(download_with_retry "$chromedriver_url") 75 | unzip -qq "$driver_archive_path" -d /usr/local/share 76 | 77 | chmod +x $chromedriver_bin 78 | ln -s "$chromedriver_bin" /usr/bin/ 79 | set_etc_environment_variable "CHROMEWEBDRIVER" "${CHROMEDRIVER_DIR}" 80 | 81 | # Download and unpack Chromium 82 | chrome_revision=$(echo "${chrome_versions_json}" | jq -r '.builds["'"$chrome_version"'"].revision') 83 | chromium_revision=$(get_chromium_revision "$chrome_revision") 84 | chromium_url="https://www.googleapis.com/download/storage/v1/b/chromium-browser-snapshots/o/Linux_x64%2F${chromium_revision}%2Fchrome-linux.zip?alt=media" 85 | CHROMIUM_DIR="/usr/local/share/chromium" 86 | chromium_bin="${CHROMIUM_DIR}/chrome-linux/chrome" 87 | 88 | echo "Installing chromium revision $chromium_revision" 89 | chromium_archive_path=$(download_with_retry "$chromium_url") 90 | mkdir $CHROMIUM_DIR 91 | unzip -qq "$chromium_archive_path" -d $CHROMIUM_DIR 92 | 93 | ln -s $chromium_bin /usr/bin/chromium 94 | ln -s $chromium_bin /usr/bin/chromium-browser 95 | 96 | -------------------------------------------------------------------------------- /images/ubuntu/scripts/build/install-pypy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-pypy.sh 4 | ## Desc: Install PyPy 5 | ################################################################################ 6 | 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | # Set architecture-specific variables using a case statement for clarity 12 | case "$ARCH" in 13 | "ppc64le") 14 | update_dpkgs 15 | install_dpkgs --no-install-recommends pypy 16 | exit 0 17 | ;; 18 | "s390x") 19 | # /tmp/pypy3.9-v7.3.16-s390x/bin/pypy3: error while loading shared libraries: libffi.so.6: cannot open shared object file: 20 | echo "No actions defined for $ARCH architecture." 21 | exit 0 22 | ;; 23 | "x86_64") 24 | package_arch="x64" 25 | ;; 26 | *) 27 | package_arch="$ARCH" 28 | ;; 29 | esac 30 | 31 | # This function installs PyPy using the specified arguments: 32 | # $1=package_url 33 | install_pypy() { 34 | local package_url=$1 35 | 36 | package_tar_name=$(echo "$package_url" | awk -F/ '{print $NF}') 37 | package_name=${package_tar_name/.tar.bz2/} 38 | 39 | echo "Downloading tar archive '$package_name'" 40 | package_tar_temp_path=$(download_with_retry "$package_url") 41 | 42 | echo "Expand '$package_name' to the /tmp folder" 43 | tar xf "$package_tar_temp_path" -C /tmp 44 | 45 | # Get Python version 46 | major_version=$(echo "${package_name/pypy/}" | cut -d. -f1) 47 | python_major="python$major_version" 48 | 49 | if [ "$major_version" != 2 ]; then 50 | pypy_major="pypy$major_version" 51 | else 52 | pypy_major="pypy" 53 | fi 54 | 55 | package_temp_folder="/tmp/$package_name" 56 | python_full_version=$("$package_temp_folder/bin/$pypy_major" -c "import sys;print('{}.{}.{}'.format(sys.version_info[0],sys.version_info[1],sys.version_info[2]))") 57 | pypy_full_version=$("$package_temp_folder/bin/$pypy_major" -c "import sys;print('{}.{}.{}'.format(*sys.pypy_version_info[0:3]))") 58 | echo "Put '$pypy_full_version' to PYPY_VERSION file" 59 | echo "$pypy_full_version" > "$package_temp_folder/PYPY_VERSION" 60 | 61 | # PyPy folder structure 62 | pypy_toolcache_path=$AGENT_TOOLSDIRECTORY/PyPy 63 | pypy_toolcache_version_path=$pypy_toolcache_path/$python_full_version 64 | pypy_toolcache_version_arch_path=$pypy_toolcache_version_path/${package_arch} 65 | 66 | echo "Check if PyPy hostedtoolcache folder exist..." 67 | if [ ! -d "$pypy_toolcache_path" ]; then 68 | mkdir -p "$pypy_toolcache_path" 69 | fi 70 | 71 | echo "Create PyPy '$pypy_toolcache_version_path' folder" 72 | mkdir "$pypy_toolcache_version_path" 73 | 74 | echo "Move PyPy '$package_temp_folder' binaries to '$pypy_toolcache_version_arch_path' folder" 75 | mv "$package_temp_folder" "$pypy_toolcache_version_arch_path" 76 | 77 | echo "Create additional symlinks (Required for UsePythonVersion Azure DevOps task)" 78 | cd "$pypy_toolcache_version_arch_path"/bin 79 | 80 | # Starting from PyPy 7.3.4 these links are already included in the package 81 | [ -f ./"$python_major" ] || ln -s "$pypy_major" "$python_major" 82 | [ -f ./python ] || ln -s "$python_major" python 83 | 84 | chmod +x ./python ./"$python_major" 85 | 86 | echo "Install latest Pip" 87 | ./python -m ensurepip 88 | ./python -m pip install --ignore-installed pip 89 | 90 | echo "Create complete file" 91 | touch "$pypy_toolcache_version_path"/"${package_arch}".complete 92 | 93 | echo "Remove '$package_tar_temp_path'" 94 | rm -f "$package_tar_temp_path" 95 | } 96 | 97 | # Installation PyPy 98 | pypy_versions_json=$(curl -fsSL https://downloads.python.org/pypy/versions.json) 99 | toolset_versions=$(get_toolset_value '.toolcache[] | select(.name | contains("PyPy")) | .versions[]') 100 | 101 | for toolset_version in $toolset_versions; do 102 | latest_major_pypy_version=$(echo "$pypy_versions_json" | 103 | jq -r --arg toolset_version "$toolset_version" --arg arch "$package_arch" 'first(.[] 104 | | select((.python_version | startswith($toolset_version)) and .stable == true) | .files[] 105 | | select(.arch == $arch and .platform == "linux") | .download_url)') 106 | if [[ -z "$latest_major_pypy_version" ]]; then 107 | echo "Failed to get PyPy version '$toolset_version'" 108 | exit 1 109 | fi 110 | 111 | install_pypy "$latest_major_pypy_version" 112 | done 113 | 114 | chown -R "$SUDO_USER:$SUDO_USER" "$AGENT_TOOLSDIRECTORY/PyPy" 115 | -------------------------------------------------------------------------------- /docs/OCI_Image_Used_as_a_Self-Hosted_GitHub_Actions_Runner.md: -------------------------------------------------------------------------------- 1 | ### **OCI Image Used as a Self-Hosted GitHub Actions Runner** 2 | 3 | A **self-hosted runner** is a system you deploy and manage to execute jobs from GitHub Actions workflows on GitHub.com. This document outlines the steps to build and configure an OCI image for a self-hosted runner. 4 | 5 | #### **Additional Resources** 6 | Refer to GitHub's official documentation on self-hosted runners for detailed information: 7 | - [About Self-Hosted Runners](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners) 8 | - [Adding a Self-Hosted Runner](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/adding-self-hosted-runners) 9 | - [Hardening Self-Hosted Runners](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#hardening-for-self-hosted-runners) 10 | 11 | --- 12 | 13 | ### **Prerequisites** 14 | 1. **Docker or Podman** 15 | Ensure that either `docker` or `podman` is installed and configured on your system. 16 | 17 | --- 18 | 19 | ### **Building the Runner Images** 20 | 21 | Use the script `docker.sh` or `podman.sh` to build OCI images for the runner. 22 | 23 | #### **Command Syntax** 24 | ``` 25 | sudo ./scripts/docker.sh 26 | ``` 27 | ``` 28 | sudo ./scripts/podman.sh 29 | ``` 30 | #### **Parameters** 31 | - **`-b `**: The tool to use for building images. Defaults to `podman` or `docker` based on availability. Specify explicitly if required. 32 | - **`[distro ...]`**: Specify the distribution to build images for (`ubuntu`, `almalinux`, or `opensuse`). If omitted, images for all supported distributions are built. 33 | 34 | --- 35 | 36 | ### **Configuring Network and Firewall** 37 | 38 | To enable communication between GitHub and the self-hosted runner, you may need to adjust firewall settings: 39 | - Example for a service listening on port `5000`: 40 | ```bash 41 | firewall-cmd --add-port=5000/tcp 42 | ``` 43 | - If using multiple runners with unique ports, map each external port to port `443` within the OCI runtime. Update firewall rules accordingly. 44 | 45 | --- 46 | 47 | ### **Using the Self-Hosted Runner** 48 | 49 | #### **OCI Image Characteristics** 50 | The OCI image is ephemeral, meaning it requires configuration every time it is launched. To create an application-specific runner image: 51 | 1. Use the base runner image built earlier. 52 | 2. Pre-configure the runner with repository-specific details using a `Dockerfile`. 53 | 54 | --- 55 | 56 | ### **Creating a Pre-Configured Runner Image** 57 | 58 | #### **Sample Dockerfile** 59 | ```dockerfile 60 | FROM localhost/runner:ubuntu 61 | 62 | ARG REPO 63 | ARG TOKEN 64 | 65 | RUN /opt/runner-cache/config.sh --url ${REPO} --token ${TOKEN} 66 | 67 | CMD /opt/runner-cache/run.sh 68 | ``` 69 | 70 | #### **Build Commands** 71 | - **Docker**: 72 | ```bash 73 | docker build --build-arg TOKEN=xxxxxx --build-arg REPO=yyyyy --squash -f Dockerfile.test --tag runner:test . 74 | ``` 75 | - **Podman**: 76 | ```bash 77 | podman build --build-arg TOKEN=xxxxxx --build-arg REPO=yyyyy --squash-all -f Dockerfile.test --tag runner:test . 78 | ``` 79 | 80 | --- 81 | 82 | ### **Running the Self-Hosted Runner** 83 | 84 | #### **Start Commands** 85 | - **Docker**: 86 | ```bash 87 | docker run runner:test 88 | ``` 89 | - **Podman**: 90 | ```bash 91 | podman run runner:test 92 | ``` 93 | 94 | #### **Sample Workflow for Testing** 95 | Create a workflow file (`.github/workflows/Makefile.yml`) in your repository: 96 | ```yaml 97 | name: Makefile CI 98 | 99 | on: 100 | push: 101 | branches: [ "main" ] 102 | pull_request: 103 | branches: [ "main" ] 104 | 105 | jobs: 106 | build: 107 | runs-on: self-hosted 108 | steps: 109 | - uses: actions/checkout@v3 110 | 111 | - name: Install Dependencies 112 | run: sudo apt-get install -y golang-go 113 | 114 | - name: Build 115 | run: GOPATH=/home/ubuntu/go GOCACHE=/tmp/go make 116 | ``` 117 | 118 | --- 119 | 120 | ### **Example Run Output** 121 | When starting the runner: 122 | ```bash 123 | > podman run --rm -it runner:test 124 | 125 | √ Connected to GitHub 126 | 127 | Current runner version: '2.312.0' 128 | 2024-01-31 01:56:33Z: Listening for Jobs 129 | 2024-01-31 01:56:40Z: Running job: build 130 | 2024-01-31 01:57:39Z: Job build completed with result: Succeeded 131 | ``` 132 | 133 | #### **GitHub Actions Workflow Status** 134 | Navigate to the GitHub Actions page for your repository to view workflow execution details. 135 | -------------------------------------------------------------------------------- /images/centos/scripts/build/install-docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ################################################################################ 3 | ## File: install-docker.sh 4 | ## Desc: Install docker onto the image 5 | ## Supply chain security: amazon-ecr-credential-helper - dynamic checksum validation 6 | ################################################################################ 7 | # Source the helpers for use with the script 8 | # shellcheck disable=SC1091 9 | source "$HELPER_SCRIPTS"/install.sh 10 | 11 | # Set architecture-specific variables using a case statement for clarity 12 | case "$ARCH" in 13 | "x86_64") 14 | package_arch="amd64" 15 | ;; 16 | *) 17 | package_arch="$ARCH" 18 | ;; 19 | esac 20 | 21 | os_codename=$(. /etc/os-release && echo "$VERSION_ID") 22 | dnf -y install dnf-plugins-core 23 | dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 24 | 25 | # Install docker components which available via apt-get 26 | # Using toolsets keep installation order to install dependencies before the package in order to control versions 27 | 28 | components=$(get_toolset_value '.docker.components[] .package') 29 | for package in $components; do 30 | version=$(get_toolset_value ".docker.components[] | select(.package == \"$package\") | .version") 31 | if [[ $version == "latest" ]]; then 32 | install_dnfpkgs --no-install-recommends "$package" 33 | else 34 | version_string=$(dnf --showduplicates list "$package" | awk '{ print $2 }' | grep "$version" | grep "$os_codename" | head -1) 35 | install_dnfpkgs --no-install-recommends "${package}=${version_string}" 36 | fi 37 | done 38 | 39 | # Install plugins that are best installed from the GitHub repository 40 | # Be aware that `url` built from github repo name and plugin name because of current repo naming for those plugins 41 | 42 | plugins=$(get_toolset_value '.docker.plugins[] .plugin') 43 | for plugin in $plugins; do 44 | version=$(get_toolset_value ".docker.plugins[] | select(.plugin == \"$plugin\") | .version") 45 | filter=$(get_toolset_value ".docker.plugins[] | select(.plugin == \"$plugin\") | .asset_map[\"$ARCH\"]") 46 | url=$(resolve_github_release_asset_url "docker/$plugin" "endswith(\"$filter\")" "$version") 47 | binary_path=$(download_with_retry "$url" "/tmp/docker-$plugin") 48 | mkdir -pv "/usr/libexec/docker/cli-plugins" 49 | install "$binary_path" "/usr/libexec/docker/cli-plugins/docker-$plugin" 50 | done 51 | 52 | # docker from official repo introduced different GID generation: https://github.com/actions/runner-images/issues/8157 53 | gid=$(cut -d ":" -f 3 /etc/group | grep "^1..$" | sort -n | tail -n 1 | awk '{ print $1+1 }') 54 | groupmod -g "$gid" docker 55 | 56 | # Create systemd-tmpfiles configuration for Docker 57 | cat <