Merge changes I1fef5da1,Ie1c63a9a

* changes:
  Download jq on :download_stripped
  Update roborio setup scripts with beta
diff --git a/frc971/config/setup_roborio.sh b/frc971/config/setup_roborio.sh
index 3434482..5e3e8af 100755
--- a/frc971/config/setup_roborio.sh
+++ b/frc971/config/setup_roborio.sh
@@ -1,6 +1,7 @@
 #!/bin/bash
 #
 # Note: this should be run from within bazel
+#       and before /home/admin/bin is created by :download_stripped
 
 set -Eeuo pipefail
 
diff --git a/frc971/downloader/downloader.py b/frc971/downloader/downloader.py
index f45a162..d21d8bd 100644
--- a/frc971/downloader/downloader.py
+++ b/frc971/downloader/downloader.py
@@ -14,10 +14,10 @@
 import shutil
 
 
-def install(ssh_target, pkg, ssh_path, scp_path):
+def install(ssh_target, pkg, channel, ssh_path, scp_path):
     """Installs a package from NI on the ssh target."""
     print("Installing", pkg)
-    PKG_URL = "http://download.ni.com/ni-linux-rt/feeds/2015/arm/ipk/cortexa9-vfpv3/" + pkg
+    PKG_URL = f"http://download.ni.com/ni-linux-rt/feeds/academic/2023/arm/{channel}/cortexa9-vfpv3/{pkg}"
     subprocess.check_call(["wget", PKG_URL, "-O", pkg])
     try:
         subprocess.check_call(
@@ -75,6 +75,25 @@
     ssh_path = "external/ssh/ssh"
     scp_path = "external/ssh/scp"
 
+    # install jq
+    try:
+        subprocess.check_call([ssh_path, ssh_target, "jq", "--version"],
+                              stdout=subprocess.DEVNULL)
+    except subprocess.CalledProcessError as e:
+        if e.returncode == 127:
+            print("Didn't find jq on roboRIO, installing jq.")
+            install(ssh_target, "jq-lic_1.5-r0.35_cortexa9-vfpv3.ipk", 'extra',
+                    ssh_path, scp_path)
+            install(ssh_target, "libonig-lic_5.9.6-r0.27_cortexa9-vfpv3.ipk",
+                    'extra', ssh_path, scp_path)
+            install(ssh_target, "libonig2_5.9.6-r0.27_cortexa9-vfpv3.ipk",
+                    'extra', ssh_path, scp_path)
+            install(ssh_target, "jq_1.5-r0.35_cortexa9-vfpv3.ipk", 'extra',
+                    ssh_path, scp_path)
+
+            subprocess.check_call([ssh_path, ssh_target, "jq", "--version"],
+                                  stdout=subprocess.DEVNULL)
+
     # Since rsync is pretty fixed in what it can do, build up a temporary
     # directory with the exact contents we want the target to have.  This
     # is faster than multiple SSH connections.
@@ -130,12 +149,12 @@
         except subprocess.CalledProcessError as e:
             if e.returncode == 127 or e.returncode == 12:
                 print("Unconfigured roboRIO, installing rsync.")
-                install(ssh_target, "libattr1_2.4.47-r0.36_cortexa9-vfpv3.ipk",
-                        ssh_path, scp_path)
-                install(ssh_target, "libacl1_2.2.52-r0.36_cortexa9-vfpv3.ipk",
-                        ssh_path, scp_path)
-                install(ssh_target, "rsync_3.1.0-r0.7_cortexa9-vfpv3.ipk",
-                        ssh_path, scp_path)
+                install(ssh_target, "libacl1_2.2.52-r0.310_cortexa9-vfpv3.ipk",
+                        'main', ssh_path, scp_path)
+                install(ssh_target, "rsync-lic_3.1.3-r0.23_cortexa9-vfpv3.ipk",
+                        'extra', ssh_path, scp_path)
+                install(ssh_target, "rsync_3.1.3-r0.23_cortexa9-vfpv3.ipk",
+                        'extra', ssh_path, scp_path)
                 subprocess.check_call(rsync_cmd)
             elif e.returncode == 11:
                 # Directory wasn't created, make it and try again.  This keeps the happy path fast.