Ansible role that installs R itself, R packages (from CRAN, archived and remote repos) and associated tools.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
6.4 KiB

---
# https://docs.ansible.com/ansible/latest/collections/ansible/builtin/include_vars_module.html
- name: Include R_CRAN_packages variable
ansible.builtin.include_vars:
file: packages-CRAN.yml
- name: Include R_archived_packages variable
ansible.builtin.include_vars:
file: packages-archived.yml
- name: Include R_dev_packages variable
ansible.builtin.include_vars:
file: packages-dev.yml
# https://stackoverflow.com/questions/26985112/r-install-packages-from-shell
# https://github.com/eddelbuettel/littler
# https://adamj.eu/tech/2014/07/19/installing-and-removing-r-packages-with-ansible/
# we do this to avoid "NO DISPLAY" warnings/errors when installing some R packages
# https://stackoverflow.com/a/1710952/1198249
- name: Install virtual framebuffer X server
ansible.builtin.apt:
name:
- xvfb
- xfonts-base
state: present
# temporarily disable any ~/.Rprofile before installing R packages
# (because its output pollutes the playbook output/log)
- name: Temporarily disable ~/.Rprofile by renaming the file
ansible.builtin.command: "mv {{ ansible_env.HOME }}/.Rprofile {{ ansible_env.HOME }}/.Rprofile.moved"
ignore_errors: true
# ignore_errors in case the playbook is interrupted at this point and then restarted, file already moved
# I added xvfb-run to fix "NO DISPLAY" warnings/errors when installating certain packages
# Note: when rerunning xvfb-run, it fails to start with "Server is already active for display 99"
# This is because the already running xvfb-instance and the new instance you are trying to start
# will both try to connect to server number 99.
# The flag --auto-servernum allows the new instance to get a new number instead.
# https://github.com/plotly/orca/issues/131#issuecomment-442168670
# Based on this task below, I could probably improve the following CRAN Ansible module:
# https://github.com/yutannihilation/ansible-module-cran/blob/master/library/cran.py
- name: Install R CRAN packages
# https://stackoverflow.com/a/31009469/1198249
# RPYTHON_PYTHON_VERSION=3: otherwise rPython fails with "could not locate python-config"
ansible.builtin.command: >
xvfb-run --auto-servernum Rscript --slave --no-save --no-restore-history -e
"Sys.setenv(RPYTHON_PYTHON_VERSION=3);
if (! ('{{ item }}' %in% installed.packages()[, 'Package'])) {
install.packages(pkgs='{{ item }}', lib='{{ RLIBS_SYSTEM }}');
print('Added {{ item }}');
} else {
print('Already installed {{ item }}');
}"
register: r_cran_package
failed_when: "r_cran_package.rc != 0 or 'had non-zero exit status' in r_cran_package.stderr"
changed_when: "'Added' in r_cran_package.stdout"
with_items: "{{ R_CRAN_packages }}"
# The diffractometry package has been archived on CRAN, and does not have any git repo
# https://cran.r-project.org/src/contrib/Archive/diffractometry/
# https://stackoverflow.com/questions/18655976/install-the-package-that-has-been-removed-from-the-cran-repository-easily
# https://stackoverflow.com/a/24194531/1198249
- name: Install R CRAN archived packages
ansible.builtin.command: >
xvfb-run --auto-servernum Rscript --slave --no-save --no-restore-history -e
"if (! ('{{ item.name }}' %in% installed.packages()[, 'Package'])) {
withr::with_libpaths(
new='{{ RLIBS_SYSTEM }}',
remotes::install_version(package='{{ item.name }}', version='{{ item.version }}'));
print('Added {{ item.name }}');
} else {
print('Already installed {{ item.name }}');
}"
register: r_archive_package
failed_when: "r_archive_package.rc != 0 or 'had non-zero exit status' in r_archive_package.stderr"
changed_when: "'Added' in r_archive_package.stdout"
with_items: "{{ R_archived_packages }}"
# Install R packages from Github using remotes::install_github()
# together with withr::with_libpaths() to specify our main R library path
# For the first time ever, I hit Github's API rate limiter...
# > Unauthenticated requests only get 60/hour. https://stackoverflow.com/a/54833819
# withr::with_libpaths(new='/opt/R/4.0.5/lib/R/library', remotes::install_github('solarchemist/renishaw')
# Error: Failed to install 'renishaw' from GitHub:
# HTTP error 403. API rate limit exceeded for 81.227.200.124.
# (But here's the good news: Authenticated requests get a higher rate limit.
# Check out the documentation for more details.)
# Rate limit remaining: 0/60
# Rate limit reset at: 2022-01-27 20:16:13 UTC
# To increase your GitHub API rate limit - Use `usethis::create_github_token()` to create a
# Personal Access Token. Use `usethis::edit_r_environ()` and add the token as `GITHUB_PAT`.
#
# https://docs.ansible.com/ansible/latest/user_guide/playbooks_strategies.html#restricting-execution-with-throttle
# https://stackoverflow.com/questions/44134642/how-to-retry-ansible-task-that-may-fail
# It seems remotes:: hits the Github API more than my other Ansible tasks. So suggested fix is probably the best.
# https://github.com/r-lib/remotes/issues/210
# https://github.com/r-lib/remotes/issues/638
- name: Install R dev packages
ansible.builtin.command: >
xvfb-run --auto-servernum Rscript --slave --no-save --no-restore-history -e
"withr::with_libpaths(new='{{ RLIBS_SYSTEM }}', remotes::install_github('{{ item.repo }}'));
print('Added {{ item.name }}');"
register: r_dev_package
failed_when: "r_dev_package.rc != 0 or 'had non-zero exit status' in r_dev_package.stderr"
changed_when: "'Added' in r_dev_package.stdout"
with_items: "{{ R_dev_packages }}"
- name: Import fonts into the extrafont database and register the fonts with the PDF output device
# https://github.com/wch/extrafont#import-fonts-into-the-extrafont-database
ansible.builtin.command: >
xvfb-run --auto-servernum Rscript --slave --no-save --no-restore-history -e
"library(extrafont); font_import(prompt=FALSE); loadfonts()"
# you can view the resulting table of font information with
# > fonts()
# [1] "DejaVu Math TeX Gyre" "DejaVu Sans" "DejaVu Sans Light"
# [4] "DejaVu Sans Condensed" "DejaVu Sans Mono" "DejaVu Serif"
# [7] "DejaVu Serif Condensed" "Droid Sans Fallback" "Liberation Mono"
# [10] "Liberation Sans" "Liberation Sans Narrow" "Liberation Serif"
# [13] "Noto Mono"
# move ~/.Rprofile back
- name: Enable our ~/.Rprofile again
ansible.builtin.command: "mv {{ ansible_env.HOME }}/.Rprofile.moved {{ ansible_env.HOME }}/.Rprofile"
ignore_errors: true