diff --git a/Makefile b/Makefile index 4c9daf8..1f4f6ab 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -PLATFORMS := ubuntu-2004 ubuntu-2204 debian-10 debian-11 debian-12 centos-7 centos-8 rhel-9 opensuse-154 fedora-37 fedora-38 +PLATFORMS := ubuntu-2004 ubuntu-2204 debian-10 debian-11 debian-12 centos-7 centos-8 rhel-9 opensuse-154 opensuse-155 fedora-37 fedora-38 SLS_BINARY ?= ./node_modules/serverless/bin/serverless.js deps: diff --git a/README.md b/README.md index 2518c27..40604ca 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,9 @@ R binaries are built for the following Linux operating systems: - CentOS 7 - Red Hat Enterprise Linux 7, 8, 9 - openSUSE 15.4 +- openSUSE 15.5 - SUSE Linux Enterprise 15 SP4 +- SUSE Linux Enterprise 15 SP5 - Fedora 37, 38 Operating systems are supported until their vendor end-of-support dates, which @@ -140,6 +142,10 @@ Download the rpm package: ```bash # openSUSE 15.4 / SLES 15 SP4 curl -O https://cdn.posit.co/r/opensuse-154/pkgs/R-${R_VERSION}-1-1.x86_64.rpm + + +# openSUSE 15.5 / SLES 15 SP5 +curl -O https://cdn.posit.co/r/opensuse-155/pkgs/R-${R_VERSION}-1-1.x86_64.rpm ``` Then install the package: @@ -247,6 +253,11 @@ make build-r-$PLATFORM ## Adding a new platform. +### README + +1. Add the new platform to the `Supported Platforms` list. +2. Add rpm package download instructions for the new platform. + ### Dockerfile Create a `builder/Dockerfile.platform-version` (where `platform-version` is `ubuntu-2204` or `centos-7`, etc.) This file must contain four major tasks: @@ -256,6 +267,10 @@ Create a `builder/Dockerfile.platform-version` (where `platform-version` is `ubu 3. The `awscli`, 1.17.10+ if installed via `pip`, for uploading tarballs to S3 4. `COPY` and `ENTRYPOINT` for the `build.sh` file in `builder/`. +### Packaging script + +Create a `builder/package.platform-version` script (where `platform-version` is `ubuntu-2204` or `centos-7`, etc.). + ### docker-compose.yml A new service in the docker-compose file named according to the `platform-version` and containing the proper entries: diff --git a/builder/Dockerfile.opensuse-155 b/builder/Dockerfile.opensuse-155 new file mode 100644 index 0000000..34c55f1 --- /dev/null +++ b/builder/Dockerfile.opensuse-155 @@ -0,0 +1,103 @@ +FROM opensuse/leap:15.5 + +ENV OS_IDENTIFIER opensuse-155 + +# Most of these packages, and also the configure options that follow were determined +# by reviewing "R-base.spec" from the following OpenSUSE RPM: +# https://download.opensuse.org/repositories/devel:/languages:/R:/released/openSUSE_Leap_42.3/src/R-base-3.5.3-103.1.src.rpm + +RUN zypper --non-interactive update +RUN zypper --non-interactive --gpg-auto-import-keys -n install \ + bzip2 \ + cairo-devel \ + curl \ + fdupes \ + gcc \ + gcc-c++ \ + gcc-fortran \ + glib2-devel \ + glibc-locale \ + help2man \ + # Like openSUSE/SLES 15.4, SUSE 15.5 ships with both ICU 65 (libicu-devel) and + # ICU 69 (icu.691-devel). Prefer ICU 69 because the devel packages can't coexist, and + # zypper resolves libicu-devel to icu.691-devel when installing RPMs. + icu.691-devel \ + java-11-openjdk-devel \ + libX11-devel \ + libXScrnSaver-devel \ + libXmu-devel \ + libXt-devel \ + libbz2-devel \ + libcurl-devel \ + libjpeg-devel \ + libpng-devel \ + libtiff-devel \ + make \ + pango-devel \ + pcre-devel \ + pcre2-devel \ + perl \ + perl-macros \ + readline-devel \ + rpm-build \ + shadow \ + tcl-devel \ + texinfo \ + texlive-ae \ + texlive-bibtex \ + texlive-cm-super \ + texlive-dvips \ + texlive-fancyvrb \ + texlive-helvetic \ + texlive-inconsolata \ + texlive-latex \ + texlive-makeindex \ + texlive-metafont \ + texlive-psnfss \ + texlive-tex \ + texlive-times \ + tk-devel \ + unzip \ + wget \ + xdg-utils \ + xorg-x11-devel \ + xz-devel \ + zip \ + zlib-devel \ + && zypper clean + +# Install AWS CLI +RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-$(uname -m).zip" -o "awscliv2.zip" && \ + unzip awscliv2.zip && \ + ./aws/install && \ + rm -rf aws awscliv2.zip + +RUN if [ "$(arch)" == "aarch64" ]; then echo arm64; else echo amd64; fi > /tmp/arch + +RUN curl -LO "https://github.com/goreleaser/nfpm/releases/download/v2.18.1/nfpm_$(cat /tmp/arch).rpm" && \ + zypper --non-interactive --no-gpg-checks install "nfpm_$(cat /tmp/arch).rpm" && \ + rm "nfpm_$(cat /tmp/arch).rpm" + +RUN chmod 0777 /opt + +# Configure flags for SUSE that don't use the defaults in build.sh +ENV CONFIGURE_OPTIONS="\ + --enable-R-shlib \ + --with-tcltk \ + --with-x \ + --enable-memory-profiling \ + --with-tcl-config=/usr/lib64/tclConfig.sh \ + --with-tk-config=/usr/lib64/tkConfig.sh" + +# Make sure that patching Java does not break R. +# On SUSE, the default JAVA_HOME path always uses the major Java version only, +# but the JDK path is chosen by default. We change this to the JRE path to +# support users who only want to install the JRE (non-devel) package. +# https://cran.r-project.org/doc/manuals/r-release/R-admin.html#Java-support +# https://solutions.posit.co/envs-pkgs/using-rjava/ +ENV JAVA_HOME=/usr/lib64/jvm/jre-11-openjdk + +COPY package.opensuse-155 /package.sh +COPY build.sh . +COPY patches /patches +ENTRYPOINT ./build.sh diff --git a/builder/docker-compose.yml b/builder/docker-compose.yml index b8b0407..883422a 100644 --- a/builder/docker-compose.yml +++ b/builder/docker-compose.yml @@ -95,6 +95,18 @@ services: image: r-builds:rhel-9 volumes: - ./integration/tmp:/tmp/output + opensuse-155: + command: ./build.sh + environment: + - R_VERSION=${R_VERSION} + - R_INSTALL_PATH=${R_INSTALL_PATH} + - LOCAL_STORE=/tmp/output + build: + context: . + dockerfile: Dockerfile.opensuse-155 + image: r-builds:opensuse-155 + volumes: + - ./integration/tmp:/tmp/output opensuse-154: command: ./build.sh environment: @@ -130,4 +142,4 @@ services: dockerfile: Dockerfile.fedora-38 image: r-builds:fedora-38 volumes: - - ./integration/tmp:/tmp/output \ No newline at end of file + - ./integration/tmp:/tmp/output diff --git a/builder/package.opensuse-155 b/builder/package.opensuse-155 new file mode 100644 index 0000000..3bd9d89 --- /dev/null +++ b/builder/package.opensuse-155 @@ -0,0 +1,100 @@ +#!/bin/bash + +if [[ ! -d /tmp/output/${OS_IDENTIFIER} ]]; then + mkdir -p "/tmp/output/${OS_IDENTIFIER}" +fi + +# R 3.x requires PCRE1 +pcre_lib='pcre2-devel' +if [[ "${R_VERSION}" =~ ^3 ]]; then + pcre_lib='pcre-devel' +fi + +# Create post-install script required for OpenBLAS. +# +# On RHEL and SUSE, we link R against the internal shared BLAS to make the +# R binaries more portable and allow users to switch BLAS implementations without +# having to recompile R. We default to OpenBLAS, but users may prefer other implementations. +# +# Binary packages built against the shared BLAS are also more portable and may be used +# with the default R distributed by RHEL/SUSE, or other R installations using +# shared BLAS and configured with a different BLAS (such as Microsoft R Open with MKL). +# This is especially important for RSPM's binary packages. +# +# On Ubuntu/Debian, we link R against the external BLAS instead (--with-blas/--with-lapack), +# as those distributions use the alternatives system to swap BLAS libraries at runtime. +# The default R distributions on Ubuntu/Debian use the external BLAS, so we do as well +# for portability. +# +# https://cran.r-project.org/doc/manuals/r-release/R-admin.html#Shared-BLAS +cat <> /post-install.sh +mv ${R_INSTALL_PATH}/lib/R/lib/libRblas.so ${R_INSTALL_PATH}/lib/R/lib/libRblas.so.keep +ln -s /usr/lib64/libopenblas.so ${R_INSTALL_PATH}/lib/R/lib/libRblas.so +EOF + +# Create after-remove script to remove internal BLAS, which won't be cleaned up automatically. +cat <> /after-remove.sh +if [ -d ${R_INSTALL_PATH} ]; then + rm -r ${R_INSTALL_PATH} +fi +EOF + +if [ "$(arch)" == "aarch64" ]; then echo arm64; else echo amd64; fi > /tmp/arch + +cat < /tmp/nfpm.yml +name: R-${R_VERSION} +version: 1 +version_schema: none +arch: $(cat /tmp/arch) +release: 1 +maintainer: Posit Software, PBC +description: | + GNU R statistical computation and graphics system +vendor: Posit Software, PBC +homepage: https://www.r-project.org +license: GPLv2+ +depends: +- fontconfig +- gcc +- gcc-c++ +- gcc-fortran +- glibc-locale +- gzip +- icu.691-devel +- libbz2-devel +- libcairo2 +- libcurl-devel +- libfreetype6 +- libgomp1 +- libjpeg62 +- libopenblas_pthreads-devel +- libpango-1_0-0 +- libreadline7 +- libtiff5 +- make +- ${pcre_lib} +- tar +- tcl +- tk +- unzip +- which +- xorg-x11 +- xorg-x11-fonts-100dpi +- xorg-x11-fonts-75dpi +- xz-devel +- zip +- zlib-devel +contents: +- src: ${R_INSTALL_PATH} + dst: ${R_INSTALL_PATH} +scripts: + postinstall: /post-install.sh + postremove: /after-remove.sh +EOF + +nfpm package \ + -f /tmp/nfpm.yml \ + -p rpm \ + -t "/tmp/output/${OS_IDENTIFIER}" + +export PKG_FILE=$(ls /tmp/output/${OS_IDENTIFIER}/R-${R_VERSION}*.rpm | head -1) diff --git a/install.sh b/install.sh index 4b9a51f..3fe8440 100755 --- a/install.sh +++ b/install.sh @@ -210,9 +210,11 @@ download_url () { echo "${CDN_URL}/opensuse-42/pkgs/${name}" ;; "LEAP15" | "SLES15") - if [ "${ver}" -ge 154 ]; then + if [ "${ver}" -ge 155 ]; then + echo "${CDN_URL}/opensuse-155/pkgs/${name}" + elif [ "${ver}" -eq 154 ]; then echo "${CDN_URL}/opensuse-154/pkgs/${name}" - elif [ "${ver}" -ge 153 ]; then + elif [ "${ver}" -eq 153 ]; then echo "${CDN_URL}/opensuse-153/pkgs/${name}" elif [ "${ver}" -eq 152 ]; then echo "${CDN_URL}/opensuse-152/pkgs/${name}" diff --git a/serverless-resources.yml b/serverless-resources.yml index 246b33e..b167262 100644 --- a/serverless-resources.yml +++ b/serverless-resources.yml @@ -258,6 +258,20 @@ rBuildsBatchJobDefinitionRhel9: Image: "#{AWS::AccountId}.dkr.ecr.#{AWS::Region}.amazonaws.com/r-builds:rhel-9" Timeout: AttemptDurationSeconds: 7200 +rBuildsBatchJobDefinitionOpensuse155: + Type: AWS::Batch::JobDefinition + Properties: + Type: container + ContainerProperties: + Command: + - ./build.sh + Vcpus: 4 + Memory: 4096 + JobRoleArn: + "Fn::GetAtt": [ rBuildsEcsTaskIamRole, Arn ] + Image: "#{AWS::AccountId}.dkr.ecr.#{AWS::Region}.amazonaws.com/r-builds:opensuse-155" + Timeout: + AttemptDurationSeconds: 7200 rBuildsBatchJobDefinitionOpensuse154: Type: AWS::Batch::JobDefinition Properties: diff --git a/serverless.yml b/serverless.yml index 57a1827..7f7fef2 100644 --- a/serverless.yml +++ b/serverless.yml @@ -71,13 +71,15 @@ provider: Ref: rBuildsBatchJobDefinitionCentos8 JOB_DEFINITION_ARN_rhel_9: Ref: rBuildsBatchJobDefinitionRhel9 + JOB_DEFINITION_ARN_opensuse_155: + Ref: rBuildsBatchJobDefinitionOpensuse155 JOB_DEFINITION_ARN_opensuse_154: Ref: rBuildsBatchJobDefinitionOpensuse154 JOB_DEFINITION_ARN_fedora_37: Ref: rBuildsBatchJobDefinitionFedora37 JOB_DEFINITION_ARN_fedora_38: Ref: rBuildsBatchJobDefinitionFedora38 - SUPPORTED_PLATFORMS: ubuntu-2004,ubuntu-2204,debian-10,debian-11,debian-12,centos-7,centos-8,rhel-9,opensuse-154,fedora-37,fedora-38 + SUPPORTED_PLATFORMS: ubuntu-2004,ubuntu-2204,debian-10,debian-11,debian-12,centos-7,centos-8,rhel-9,opensuse-154,opensuse-155,fedora-37,fedora-38 functions: queueBuilds: diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 4ba742b..764167f 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -63,6 +63,14 @@ services: - R_VERSION=${R_VERSION} volumes: - ../:/r-builds + opensuse-155: + image: opensuse/leap:15.5 + command: /r-builds/test/test-zypper.sh + environment: + - OS_IDENTIFIER=opensuse-155 + - R_VERSION=${R_VERSION} + volumes: + - ../:/r-builds opensuse-154: image: opensuse/leap:15.4 command: /r-builds/test/test-zypper.sh