So, I do not want to have to go through the whole process to start XINU each time I want to test thing. It’s painful. So, being a CS major I of course decided to automate it a bit better. The original reference for this comes from this Ed Discussion post, however I had to do some modification to the expect script and also made my own ways of running it so that it was easier for me. First in this I’ll cover the proper process to start it, one to have it saved, and two so that you can more easily understand how the actual easy start stuff works. Or you can just scroll down if you don’t care.

What you’re supposed to do

  • The command cs-status -c quark will print out a list of all galileo machines available. It will show any machines that are currently open and that are in use. Find one that’s not in use and remember its number.
  • CD into the xinu-spring2024/compile directory
  • Run make
    • Optionally you can run make clean first, I often have to do this anytime I edit the prototypes file to include something new
  • Once the code has all finished compiling, its time to connect to our galileo machine
  • Run cs-console galileo plus the number of the machine you’re going to use. e.g. cs-console galileo150
    • IMPORTANT: Do this in the xinu-spring2024/compile directory still
  • You should see the terminal say “connection …”
  • Now press CTRL+SPACE or CTRL+@ to enter command mode
  • In command mode, type d to tell it you want to download a file
  • Then tell it to download xinu.xbin. This assumes you are in the compile directory
  • Then press CTRL+SPACE or CTRL+@ again to go back into command mode
  • Press p to trigger a power cycle of the machine
  • After some time and lots of fancy things happening on your terminal, you will be loaded into your XINU system
    • While its loading and has spots for interaction, you should be able to leave it and it’ll work on its own
  • To exit your XINU instance, press CTRL+SPACE or CTRL+@ again to trigger command mode and then press q to quit

Automation time

There are two files that are important here. First is the run.exp file, the expect script. This file needs to be placed into your xinu-spring2024/compile folder. I have commented the code below to show what things are doing and kind of explain how it works (in my understanding). You can copy paste this directly into the file, no changes should need to be made (I think). Make sure after creating the file you run on it chmod u+x run.exp to make it executable.

#!/usr/bin/expect -f
 
# Check if the machine variable is provided as an argument
if { $argc != 1 } {
    send_user "Usage: $argv0 <machine>\n"
    exit 1
}
 
# Set the machine variable from the command line argument
set machine [lindex $argv 0]
 
set timeout -1
 
# Spawn a new shell to work in
spawn $env(SHELL)
# Increase the matching for expect
match_max 100000
# `send` sends the text directly to the shell instance. This is basically equivalent to you typing `make` and hitting enter in the shell
send -- "make\r"
# `expect` basically tells the script to wait until it sees that output in the shell, all the text in expects here should be correct
expect "Loading object files to produce GRUB bootable xinu\r
\r
Building ../compile/xinu.bin\r
\r
Building ../compile/xinu.xbin\r
\r"
send -- "cs-console $machine\r"
expect "class 'quark', host 'xinuserver.cs.purdue.edu'\r"
# This is something a bit different, \x00 refers to a control character. This one specifically is the NULL control character, which is what happens when you press CTRL+SPACE or CTRL+@
# We are effectively pressing the key combination in our shell via code with this
send -- "\x00"
expect -exact "
\r
\r(command-mode) "
# Download our xinu.xbin compiled earlier
send -- "d"
expect "file:"
send -- "xinu.xbin\r"
expect "cp-download complete"
# We sleep for a second to make sure we don't press our key combination too early
sleep 2
send -- "\x00"
expect -exact "
\r
\r(command-mode) "
# Trigger the power cycle
send -- "p"
# This lets us set a key combination that will trigger some more code. The \x1b refers to the ESCAPE character, which you get by (obviously) hitting escape on your keyboard.
# Inside we send another \x00 to trigger command mode, wait a sec to make sure it triggers, and then press q to quit. The expect script then exits
interact "\x1b" {
  send -- "\x00"
  sleep 1
  send -- "q"
  exit
}

This alone would work as automation. You just go into the compile directory and run ./run.exp INSERTMACHINEHERE e.g. ./run.exp galileo150. You could stop here. But we’re CS majors. We want it as easy as possible. So there’s more of course.
So the next thing. Create a file in your home directory called, well really whatever you want but I made mine .xinu.sh to keep it a hidden file. Again make sure its executable via chmod u+x whatever file name is

# Store the current working directory
current_directory=$(pwd)
# cd into our compile directory. YOU MAY NEED TO CHANGE THIS DEPENDING ON YOUR SETUP
cd ~/xinu-spring2024/compile
 
# I wanted a way to also easily run make clean, so if you run this script with clean as an argument it will run make clean before running the expect script
if [ "$1" = "clean" ]; then
	make clean
fi
 
# Run cs-status to get a list of machines and filter for open machines
available_machines=$(cs-status -c quark | grep -E 'quark\s+user=\s+time=' | awk '{print $1}')
 
# Select the first open machine
# Importantly, we shuffle the list that way we don't just get the first open one. So if multiple people use this it will not just go down the line.
# This also means that everytime you run the script it will use a different machine. This can be useful, since it lets you check if the problem is occuring on just one machine or not by just rerunning the script. Anytime you run into issues connecting, you can just try rerunning the script and it'll try a different machine (usually, obviously a random chance).
selected_machine=$(echo "$available_machines" | shuf -n 1)
 
# Check if any machine is available
if [ -z "$selected_machine" ]; then
    echo "No open machines found."
    exit 1
fi
# Run our expect script giving it the selected machine as an argument.
# Remember, the expect script runs make so we don't have to actually compile our code earlier, just clean if we need to
./run.exp "$selected_machine"
 
# The code will continue down here once run.exp has exited
 
# Clear the screen for convenience
clear
 
# Change back to the previous working directory (so you can continue editing whatever file you were working in)
cd "$current_directory"
 
# Echo the exit message for convenience
echo "You have exited xinu and are now in $current_directory"

Notice that there is a path being cd’ed to. Change that path to be wherever your xinu-spring2024 is located. If you are locating it in many places based on the lab you’re working on, you may want to modify this script to take an argument or something. Feel free to add things and share! This is just what works for me. Of course, now you just run ./xinu.sh and it should take care of everything for you. You can also optionally do ./xinu.sh clean to ensure the make clean is run first. But I’m exceptionally lazy, we go one step further.
I just want to type xinu and be done. So I added an alias to my ~/.bashrc.

alias xinu="~/.xinu.sh"

This lets me just type xinu from wherever and it will refer to the file .xinu.sh in my home directory. It even carries over the arguments. Aliases are great, I use them for a lot of stuff (like saving SSH strings).
There ya go. There’s my process for automating the whole thing a bit more. Now when I want to run my XINU instance I just type xinu in the terminal and it does its thing. If you find any problems or make any variations of this let me know, I’d love to see them! Good luck with class :)