Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 35 additions & 6 deletions noble/geoscripting-gui.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,18 @@
become: yes
vars:
rstudio_version: 2025.05.1-513
rstudio_branch: jammy
rstudio_branch: "{{ ubuntu_codename | default('jammy') }}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want to pass the codename. As you can see, this is Noble, but the branch is Jammy. It wouldn't work with "Noble", as RStudio people are lazy and don't maintain multiple versions as long as deps don't break.

arch: "{{ system_arch | default('amd64') }}"


tasks:
- name: Display system information
debug:
msg:
- "Installing on {{ arch }} architecture"
- "Using Ubuntu codename: {{ rstudio_branch }}"
- "RStudio version: {{ rstudio_version + ' (stable)' if arch == 'amd64' else 'Latest daily build' }} ({{ arch }})"

- name: Gather package facts
package_facts:
manager: apt
Expand All @@ -26,6 +35,7 @@
- git-cola
- oxygen-icon-theme
- rkward
- cmake

- name: Make sure local applications path exists
file:
Expand All @@ -37,9 +47,24 @@
src: ../common/git-gui.desktop
dest: /usr/local/share/applications/git-gui.desktop

- name: Install RStudio desktop
- name: Get latest RStudio daily build info for ARM64
uri:
url: https://dailies.rstudio.com/rstudio/latest/index.json
method: GET
return_content: yes
register: rstudio_daily_info
when: arch == "arm64"

- name: Install RStudio desktop (AMD64 - stable release)
apt:
deb: https://download1.rstudio.org/electron/{{ rstudio_branch }}/amd64/rstudio-{{ rstudio_version }}-amd64.deb
deb: https://download1.rstudio.org/electron/{{ rstudio_branch }}/{{ arch }}/rstudio-{{ rstudio_version }}-{{ arch }}.deb
when: arch == "amd64"

- name: Install RStudio desktop (ARM64 - daily build)
apt:
deb: "{{ (rstudio_daily_info.content | from_json).products.electron.platforms[rstudio_branch + '-arm64'].link }}"
when: arch == "arm64"


- name: Fix RStudio sandbox permissions
ansible.builtin.file:
Expand All @@ -54,11 +79,15 @@
force: true


- name: Install Google Earth
- name: Install Google Earth (AMD64)
apt:
deb: https://dl.google.com/dl/earth/client/current/google-earth-stable_current_amd64.deb
when: '"google-earth-pro-stable" not in ansible_facts.packages'
when: '"google-earth-pro-stable" not in ansible_facts.packages and arch == "amd64"'

- name: Skip Google Earth installation on ARM64
debug:
msg: "Google Earth is not available for ARM64 architecture, skipping installation"
when: arch == "arm64"

- name: Add VSCode repo key
ansible.builtin.get_url:
Expand All @@ -69,7 +98,7 @@

- name: Add VSCode repository
apt_repository:
repo: "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main"
repo: "deb [arch={{ arch }}] https://packages.microsoft.com/repos/vscode stable main"
filename: vscode

- name: Install VSCode
Expand Down
56 changes: 53 additions & 3 deletions noble/install.sh
100644 → 100755
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are also a bit too extensive changes. Just add a minimal check for the arch. You can literally just pass system_arch=$(uname -m) (or uname -i, not sure which one is set on ARM, or maybe both as on x86_64)

Original file line number Diff line number Diff line change
@@ -1,3 +1,53 @@
#!/bin/sh
bash ./install-common.sh
ansible-playbook -K --connection=local -i 127.0.0.1, geoscripting-gui.yml
#!/bin/bash

# Detect system architecture
ARCH=$(uname -m)
case $ARCH in
x86_64)
SYSTEM_ARCH="amd64"
echo "✓ Detected system architecture: AMD64 (x86_64)"
;;
aarch64)
SYSTEM_ARCH="arm64"
echo "✓ Detected system architecture: ARM64 (aarch64)"
;;
*)
echo "⚠ Warning: Unsupported architecture detected: $ARCH"
echo "This installation script supports AMD64 and ARM64 architectures only."
exit 1
;;
esac

# Detect Ubuntu version
if [ -f /etc/os-release ]; then
. /etc/os-release
if [ "$ID" = "ubuntu" ]; then
echo "✓ Detected Ubuntu version: $VERSION ($VERSION_CODENAME)"
UBUNTU_VERSION=$VERSION_ID
UBUNTU_CODENAME=$VERSION_CODENAME
else
echo "⚠ Warning: This script is designed for Ubuntu systems."
echo "Detected OS: $PRETTY_NAME"
echo "Proceeding anyway, but some packages may not be available..."
fi
else
echo "⚠ Warning: Could not detect OS version. /etc/os-release not found."
echo "Assuming Ubuntu and proceeding..."
fi

echo ""
echo "Starting installation with the following configuration:"
echo "- Architecture: $SYSTEM_ARCH"
echo "- Ubuntu Version: ${VERSION:-Unknown}"
echo "- Ubuntu Codename: ${VERSION_CODENAME:-Unknown}"
echo ""

# Check if install-common.sh exists before trying to run it
if [ -f "./install-common.sh" ]; then
bash ./install-common.sh
else
echo "Note: install-common.sh not found, skipping..."
fi

# Run ansible playbook with architecture variable
ansible-playbook -K --connection=local -i 127.0.0.1, geoscripting-gui.yml --extra-vars "system_arch=$SYSTEM_ARCH ubuntu_codename=${UBUNTU_CODENAME:-jammy}"
175 changes: 175 additions & 0 deletions noble/scripts/update_rstudio_version.py
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is overly complicated, I think. It would take more effort to run it than to set the new version manually. At most some simple Bash script could work, but we can just omit these.

Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
#!/usr/bin/env python3
"""
RStudio Version Updater
Checks for the latest stable RStudio version and updates the Ansible playbook if needed.
"""

import re
import sys
import os
import subprocess

# Try to import requests, install if missing
try:
import requests
except ImportError:
print("📦 Installing required Python package: requests")
try:
subprocess.check_call([sys.executable, "-m", "pip", "install", "requests"])
import requests
print("✅ Successfully installed requests")
except Exception as e:
print(f"❌ Failed to install requests: {e}")
print("Please install it manually: python3 -m pip install requests")
sys.exit(1)

def get_latest_stable_version():
"""Fetch the latest stable RStudio version from the official download page."""
try:
response = requests.get('https://posit.co/download/rstudio-desktop/', timeout=10)
response.raise_for_status()
content = response.text

# Pattern for Ubuntu DEB files: rstudio-VERSION-amd64.deb
deb_pattern = r'rstudio-([0-9]+\.[0-9]+\.[0-9]+-[0-9]+)-amd64\.deb'
matches = re.findall(deb_pattern, content)

if matches:
# Get unique versions and return the latest
versions = list(set(matches))
latest_version = sorted(versions, reverse=True)[0]
return latest_version
else:
print("⚠ No version patterns found on the download page")
return None

except Exception as e:
print(f"❌ Error fetching latest version: {e}")
return None

def get_current_version_from_playbook(playbook_path):
"""Extract the current RStudio version from the Ansible playbook."""
try:
with open(playbook_path, 'r') as f:
content = f.read()

# Look for rstudio_version: VERSION pattern
version_pattern = r'rstudio_version:\s*([0-9]+\.[0-9]+\.[0-9]+-[0-9]+)'
match = re.search(version_pattern, content)

if match:
return match.group(1)
else:
print("⚠ Could not find rstudio_version in playbook")
return None

except Exception as e:
print(f"❌ Error reading playbook: {e}")
return None

def update_playbook_version(playbook_path, old_version, new_version):
"""Update the RStudio version in the Ansible playbook."""
try:
with open(playbook_path, 'r') as f:
content = f.read()

# Replace the version
old_line = f"rstudio_version: {old_version}"
new_line = f"rstudio_version: {new_version}"
updated_content = content.replace(old_line, new_line)

if updated_content != content:
# Create backup
backup_path = f"{playbook_path}.backup"
with open(backup_path, 'w') as f:
f.write(content)
print(f"📁 Created backup: {backup_path}")

# Write updated version
with open(playbook_path, 'w') as f:
f.write(updated_content)
print(f"✅ Updated {playbook_path}")
return True
else:
print("⚠ No changes made to playbook")
return False

except Exception as e:
print(f"❌ Error updating playbook: {e}")
return False

def verify_version_accessibility(version):
"""Verify that the new version is accessible via download URL."""
test_url = f"https://download1.rstudio.org/electron/jammy/amd64/rstudio-{version}-amd64.deb"

try:
response = requests.head(test_url, timeout=10)
if response.status_code == 200:
size = response.headers.get('content-length', 'Unknown')
if size != 'Unknown':
size_mb = round(int(size) / (1024*1024), 1)
print(f"✅ Version {version} verified: {size_mb} MB")
else:
print(f"✅ Version {version} verified")
return True
else:
print(f"❌ Version {version} not accessible: HTTP {response.status_code}")
return False
except Exception as e:
print(f"❌ Error verifying version {version}: {e}")
return False

def main():
# Look for playbook in parent directory
script_dir = os.path.dirname(os.path.abspath(__file__))
playbook_path = os.path.join(os.path.dirname(script_dir), "geoscripting-gui.yml")

if not os.path.exists(playbook_path):
print(f"❌ Playbook not found: {playbook_path}")
print("Please ensure geoscripting-gui.yml exists in the parent directory.")
sys.exit(1)

print("RStudio Version Checker")
print("=" * 30)

# Get current version from playbook
current_version = get_current_version_from_playbook(playbook_path)
if not current_version:
sys.exit(1)

print(f"Current version in playbook: {current_version}")

# Get latest stable version
latest_version = get_latest_stable_version()
if not latest_version:
sys.exit(1)

print(f"Latest stable version: {latest_version}")

# Compare versions
if current_version == latest_version:
print("✅ Playbook is up to date!")
sys.exit(0)

print(f"🔄 Update available: {current_version} → {latest_version}")

# Verify new version is accessible
if not verify_version_accessibility(latest_version):
print("❌ Cannot update to inaccessible version")
sys.exit(1)

# Ask for confirmation
response = input(f"Update playbook to version {latest_version}? [y/N]: ").strip().lower()

if response in ['y', 'yes']:
if update_playbook_version(playbook_path, current_version, latest_version):
print("🎉 Update completed successfully!")
print(f"Updated from {current_version} to {latest_version}")
else:
print("❌ Update failed")
sys.exit(1)
else:
print("Update cancelled")

if __name__ == "__main__":
main()
Loading