Skip to content

Commit

Permalink
Add R-Studio appliance (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
sd109 authored Oct 19, 2023
1 parent 7af38a0 commit ca870f9
Show file tree
Hide file tree
Showing 6 changed files with 269 additions and 0 deletions.
26 changes: 26 additions & 0 deletions .github/builds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,32 @@
- ansible/roles/linux-monitoring/**
- ansible/roles/linux-zenith-client/**
- name: linux-rstudio
template: linux-rstudio
var-files: common,kvm,linux,ubuntu-jammy
path-filters: |
paths:
- .github/workflows/pr.yml
- bin/*
- config.pkr.hcl
- requirements.yml
- env/*/common.env
- env/*/kvm.env
- env/*/linux.env
- env/*/ubuntu-jammy.env
- vars/*/common.json
- vars/*/kvm.json
- vars/*/linux.json
- vars/*/ubuntu-jammy.json
- packer/linux-rstudio.pkr.hcl
- ansible/linux-rstudio.yml
- ansible/roles/linux-rstudio/**
- ansible/roles/linux-ansible-init/**
- ansible/roles/linux-monitoring/**
- ansible/roles/linux-podman/**
- ansible/roles/linux-data-volumes/**
- ansible/roles/linux-zenith-client/**
# For now, we build Kubernetes images for focal _and_ jammy
- name: kubernetes-1-25-focal
template: kubernetes
Expand Down
6 changes: 6 additions & 0 deletions ansible/linux-rstudio.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---

- hosts: all
become: yes
roles:
- linux-rstudio
21 changes: 21 additions & 0 deletions ansible/roles/linux-rstudio/files/rstudio-server-playbook.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
- hosts: localhost
gather_facts: true
become: true
vars:
os_metadata: "{{ lookup('url', 'http://169.254.169.254/openstack/latest/meta_data.json') | from_json }}"
os_user_metadata: "{{ os_metadata.get('meta', {}) }}"
os_project_id: "{{ os_metadata.project_id }}"
tasks:
- name: Ensure rstudio-server service is enabled and started
service:
name: rstudio-server
state: started
enabled: yes

- name: Ensure symbolic link to data volume exists in rstudio home dir
ansible.builtin.file:
src: /data
dest: /home/rstudio/data
owner: rstudio
group: rstudio
state: link
78 changes: 78 additions & 0 deletions ansible/roles/linux-rstudio/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---

- name: Update apt cache
apt:
update_cache: yes
when: ansible_os_family == "Debian"

- name: Ensure up-to-date CA certificates
package:
name: ca-certificates
state: latest

# Required for become to an unprivileged user to work
# Using the apt module seems to work more reliably than package :-/
- name: Install ACL package
apt:
update_cache: yes
name: acl
state: present
when: ansible_os_family == "Debian"

- include_role:
name: linux-ansible-init

- include_role:
name: linux-podman
tasks_from: install.yml

- include_role:
name: linux-data-volumes
vars:
data_volumes:
- metadata_var: zenith_volume_id
mountpoint: /etc/zenith/ssh
opts: "defaults,nofail"
owner: podman
group: podman
- metadata_var: data_volume_id
mountpoint: /data
opts: "defaults,nofail"
owner: podman
group: podman

- include_tasks: rstudio.yml

- name: Install rstudio ansible-init playbook
copy:
src: rstudio-server-playbook.yml
# Execute between data volumes and zenith client
dest: /etc/ansible-init/playbooks/50-rstudio.yml

- include_role:
name: linux-monitoring
vars:
prometheus_data_directory: /data/prometheus/database

- name: Install systemd unit for rstudio pod
include_role:
name: linux-podman
tasks_from: systemd-unit.yml
vars:
podman_service_name: rstudio
podman_service_type: pod

- include_role:
name: linux-zenith-client
vars:
zenith_client_name: rstudio-zenith-client
# The deb install of rstudio-server creates a systemd unit for us
zenith_client_wants: [rstudio-server]
zenith_client_pod: rstudio
zenith_forward_to_host: "HOST_IP"
zenith_forward_to_port: 8787
zenith_registrar_token_metadata_key: zenith_registrar_token_rstudio
zenith_client_playbook_priority: "51"

- name: Run cloud-init cleanup
command: cloud-init clean --logs --seed
54 changes: 54 additions & 0 deletions ansible/roles/linux-rstudio/tasks/rstudio.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---

- name: Ensure R repo apt key is downloaded
ansible.builtin.get_url:
url: https://cloud.r-project.org/bin/linux/ubuntu/marutter_pubkey.asc
dest: /etc/apt/trusted.gpg.d/cran_ubuntu_key.asc

- name: Ensure R apt repository is present
ansible.builtin.apt_repository:
repo: deb https://cloud.r-project.org/bin/linux/ubuntu {{ ansible_distribution_release }}-cran40/
state: present

- name: Ensure required system packages are installed
ansible.builtin.apt:
package:
- r-base
# Required by `deb` option in R-Studio Server install task
- xz-utils
# To allow non-root rstudio user to manage a python venv
# (https://support.posit.co/hc/en-us/articles/360023654474-Installing-and-Configuring-Python-with-RStudio)
- python3-venv
- python3-pip
update_cache: true
state: present

- name: Ensure R-Studio Server is installed
ansible.builtin.apt:
deb: https://download2.rstudio.org/server/{{ ansible_distribution_release }}/amd64/rstudio-server-2023.06.1-524-amd64.deb
state: present

- name: Ensure rstudio user exists
ansible.builtin.user:
name: rstudio
password: "{{ 'rstudio' | password_hash('sha512', 'irrelevant') }}"

- name: Ensure rstudio user has passwordless sudo permissions
community.general.sudoers:
name: rstudio
user: rstudio
commands: ALL

- name: Ensure auth is disabled in rstudio config file
ansible.builtin.blockinfile:
block: |
auth-none=1
path: /etc/rstudio/rserver.conf

- name: Ensure rstudio-server systemd override file is populated
ansible.builtin.blockinfile:
path: /etc/systemd/system/rstudio-server.service.d/override.conf
create: true
block: |
[Service]
Environment=USER=rstudio
84 changes: 84 additions & 0 deletions packer/linux-rstudio.pkr.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Use like:
# $ PACKER_LOG=1 packer build --on-error=ask -var-file=<something>.pkrvars.hcl openstack.pkr.hcl

# "timestamp" template function replacement:s
locals { timestamp = formatdate("YYMMDD-hhmm", timestamp())}

variable "source_image_name" {
type = string
}

variable "network" {
type = string
}

variable "floating_ip" {
type = string
}

variable "flavor" {
type = string
}

variable "security_groups" {
type = list(string)
}

variable "volume_size" {
type = number
default = 10
}

variable "disk_format" {
type = string
default = "qcow2"
}

variable "distro_name" {
type = string
}

variable "ssh_username" {
type = string
}

variable "skip_create_image" {
type = bool
default = false
}

source "openstack" "linux-rstudio" {
# Allow image creation to be skipped for build tests
skip_create_image = var.skip_create_image

image_name = "${var.distro_name}-linux-rstudio-${local.timestamp}"
image_visibility = "private"
image_disk_format = var.disk_format

source_image_name = var.source_image_name
flavor = var.flavor
networks = [var.network]
security_groups = var.security_groups
floating_ip = var.floating_ip

use_blockstorage_volume = true
volume_size = var.volume_size

communicator = "ssh"
ssh_username = var.ssh_username
ssh_clear_authorized_keys = true
}

build {
source "source.openstack.linux-rstudio" { }

provisioner "ansible" {
galaxy_file = "${path.root}/../requirements.yml"
playbook_file = "${path.root}/../ansible/linux-rstudio.yml"
use_proxy = false
extra_arguments = ["-v"]
ansible_env_vars = ["ANSIBLE_SSH_RETRIES=10"]
}

post-processor "manifest" { }
}

0 comments on commit ca870f9

Please sign in to comment.