Skip to content

Commit

Permalink
Add Python compatibility check
Browse files Browse the repository at this point in the history
- Fixes #125
  • Loading branch information
virtuald committed Feb 28, 2025
1 parent 96f8157 commit 760d8e7
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 6 deletions.
54 changes: 49 additions & 5 deletions robotpy_installer/cli_deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

from . import pypackages, pyproject, roborio_utils, sshcontroller
from .installer import PipInstallError, PythonMissingError, RobotpyInstaller
from .installer import _ROBOTPY_PYTHON_VERSION_TUPLE as required_pyversion
from .errors import Error
from .utils import handle_cli_error, print_err, yesno

Expand Down Expand Up @@ -349,6 +350,14 @@ def _get_robot_packages(
self._robot_packages = pypackages.make_packages(rio_packages)
return self._robot_packages

def _clear_pip_packages(self, installer: RobotpyInstaller):
rio_packages = self._get_robot_packages(installer.ssh)
to_uninstall = [p for p in rio_packages.keys() if p != "pip"]
if to_uninstall:
installer.pip_uninstall(to_uninstall)

self._packages_in_cache = None

def _ensure_requirements(
self,
project: typing.Optional[pyproject.RobotPyProjectToml],
Expand All @@ -361,6 +370,7 @@ def _ensure_requirements(
no_uninstall: bool,
):
python_exists = False
python_invalid: typing.Union[bool, str] = False
requirements_installed = False

installer = RobotpyInstaller()
Expand All @@ -383,6 +393,33 @@ def _ensure_requirements(
if not python_exists:
logger.warning("Python is not installed on RoboRIO")

if python_exists:
with wrap_ssh_error("getting python version"):
python_version = roborio_utils.get_python3_version(ssh)

if python_version != required_pyversion:
python_exists = False
m, mn = python_version
rm, rmn = required_pyversion
python_invalid = f"python{m}{mn}"

if no_install:
raise Error(
f"Unsupported version of python ({m}.{mn}) was found on the roboRIO\n"
"- could not update it because no-install was specified\n"
)

# Warn the user before changing their rio
print(
"\n"
f"Deployer has detected that the version of Python installed on the RoboRIO ({m}.{mn})\n"
"is not supported by this installer. The installer will now uninstall that\n"
f"and install Python {rm}.{rmn}.\n"
)

if not yesno("Reinstall Python"):
raise Error("User declined reinstallation")

if python_exists:
if no_install:
requirements_installed = True
Expand Down Expand Up @@ -440,6 +477,7 @@ def _ensure_requirements(
if (
cpp_java_exists
or not python_exists
or python_invalid
or not requirements_installed
or not kill_script_updated
):
Expand Down Expand Up @@ -469,6 +507,16 @@ def _ensure_requirements(
if cpp_java_exists:
roborio_utils.uninstall_cpp_java_admin(installer.ssh)

if python_invalid:
with wrap_ssh_error("uninstalling python"):
self._clear_pip_packages(installer)
logger.info("Uninstalling %s from RoboRIO", python_invalid)
installer.ssh.exec_cmd(
f"opkg remove {python_invalid}",
check=True,
print_output=True,
)

if not python_exists:
try:
installer.install_python()
Expand Down Expand Up @@ -508,11 +556,7 @@ def _ensure_requirements(
# environment is to first clear the environment.
# - can't do a partial uninstall without completely
# resolving everything

rio_packages = self._get_robot_packages(installer.ssh)
to_uninstall = [p for p in rio_packages.keys() if p != "pip"]
if to_uninstall:
installer.pip_uninstall(to_uninstall)
self._clear_pip_packages(installer)

logger.info("Installing project requirements on RoboRIO:")
for package in packages:
Expand Down
3 changes: 2 additions & 1 deletion robotpy_installer/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
]

_ROBOTPY_PYTHON_PLATFORM = "linux_roborio"
_ROBOTPY_PYTHON_VERSION_NUM = "313"
_ROBOTPY_PYTHON_VERSION_TUPLE = (3, 13)
_ROBOTPY_PYTHON_VERSION_NUM = "".join(map(str, _ROBOTPY_PYTHON_VERSION_TUPLE))
_ROBOTPY_PYTHON_VERSION = f"python{_ROBOTPY_PYTHON_VERSION_NUM}"

_PIP_STUB_PATH = "/home/admin/rpip"
Expand Down
15 changes: 15 additions & 0 deletions robotpy_installer/roborio_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,21 @@
kill_script_content: typing.Optional[bytes] = None


def get_python3_version(ssh: SshController) -> typing.Tuple[int, int]:
r = ssh.check_output(
"/usr/local/bin/python3 -c 'import json, sys; json.dump(tuple(sys.version_info), sys.stderr)'"
)

python_version = json.loads(r)
assert isinstance(python_version, list)
python_version = tuple(python_version[:2])
assert len(python_version) == 2

logger.debug("RoboRIO has Python %s.%s installed", *python_version)

return python_version


def uninstall_cpp_java_lvuser(ssh: SshController) -> bool:
"""
Frees up disk space by removing FRC C++/Java programs. This runs as lvuser or admin.
Expand Down

0 comments on commit 760d8e7

Please sign in to comment.