Skip to content

Commit 90fe872

Browse files
Copied over scss to main.scss and added stats
Copied over my scss to main.scss and added stats Most of my changes are done Most of my changes are done
1 parent 18dcbdb commit 90fe872

File tree

32 files changed

+900
-40
lines changed

32 files changed

+900
-40
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
I"B{"source"=>"/home/vivi/projects/CSHPublicSite", "destination"=>"/home/vivi/projects/CSHPublicSite/_site", "collections_dir"=>"", "cache_dir"=>".jekyll-cache", "plugins_dir"=>"_plugins", "layouts_dir"=>"_layouts", "data_dir"=>"_data", "includes_dir"=>"_includes", "collections"=>{"posts"=>{"output"=>true, "permalink"=>"/:categories/:year/:month/:day/:title:output_ext"}}, "safe"=>false, "include"=>[".htaccess"], "exclude"=>[".sass-cache", ".jekyll-cache", "gemfiles", "Gemfile", "Gemfile.lock", "node_modules", "vendor/bundle/", "vendor/cache/", "vendor/gems/", "vendor/ruby/"], "keep_files"=>[".git", ".svn"], "encoding"=>"utf-8", "markdown_ext"=>"markdown,mkdown,mkdn,mkd,md", "strict_front_matter"=>false, "show_drafts"=>nil, "limit_posts"=>0, "future"=>false, "unpublished"=>false, "whitelist"=>[], "plugins"=>["jekyll-feed", "liquid-md5", "jekyll-regex-replace"], "markdown"=>"kramdown", "highlighter"=>"rouge", "lsi"=>false, "excerpt_separator"=>"\n\n", "incremental"=>false, "detach"=>false, "port"=>"4000", "host"=>"127.0.0.1", "baseurl"=>"", "show_dir_listing"=>false, "permalink"=>"date", "paginate_path"=>"/page:num", "timezone"=>nil, "quiet"=>false, "verbose"=>false, "defaults"=>[], "liquid"=>{"error_mode"=>"warn", "strict_filters"=>false, "strict_variables"=>false}, "kramdown"=>{"auto_ids"=>true, "toc_levels"=>[1, 2, 3, 4, 5, 6], "entity_output"=>"as_char", "smart_quotes"=>"lsquo,rsquo,ldquo,rdquo", "input"=>"GFM", "hard_wrap"=>false, "guess_lang"=>true, "footnote_nr"=>1, "show_warnings"=>false, "syntax_highlighter"=>"rouge", "syntax_highlighter_opts"=>{:default_lang=>"plaintext", :guess_lang=>true}, "coderay"=>{}}, "title"=>"Computer Science House", "email"=>"[email protected]", "description"=>"Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.", "url"=>"http://localhost:4000", "twitter_username"=>"CSH_HISTORY", "github_username"=>"computersciencehouse", "theme"=>"minima", "livereload_port"=>35729, "serving"=>true, "watch"=>true}:ET
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
I"7 <h2 id="the-problem">The Problem</h2>
2+
<p>CSH currently uses Proxmox for VM hosting. It has been working great for every use case we have for it with one exception: member VM self-service. The interface isn’t very intuitive to someone who might not have created a VM before, creating a higher barrier to entry than we would like for members who might want to start learning how to use Linux for the first time. It also lacked the ability to enforce resource limits and automatically cleanup VMs that members weren’t using anymore. All of my previous major projects were much more operations and/or security focused so I figured writing something to solve this problem would be a great way to do a much more development focused project and expand my developer skillset.</p>
3+
4+
<h2 id="the-solution">The Solution</h2>
5+
<p>Proxstar (a mashup of Proxmox, a VM hosting solution, and STARRS, an IP/DNS/DHCP management system) is a web application that allows for easy VM self-service for the members of CSH. It is written in Python using Flask and runs on the CSH OpenShift cluster. RQ is being used as a task queue for tasks that take more than a second or two and periodic tasks (RQ-Scheduler). Proxstar allowed members to create, edit, and delete VMs and will automatically handle any network registration that needs to be done in STARRS for them. During creation, they can specify to either create it from a template or to install it themselves from an ISO. If creating it from a template, Proxstar will spin up a ready-to-go VM with a a user that has a randomly generated password for the member to use.</p>
6+
7+
<h4 id="making-rtps-lives-easier">Making RTPs’ Lives Easier</h4>
8+
<p>Having to periodically go through and clean up VMs that haven’t been touched by members in months can be a tedious task. Enforcing usage limits can also be difficult since Proxmox doesn’t have a mechanism for doing so. Proxstar allows RTPs to set a limit on the number of CPU cores and amount of memory and disk space a member can utilize. It also sets an expiration date on each new VM, emails the member before it expires, and automatically deletes any VMs that aren’t renewed.</p>
9+
10+
<h4 id="struggles">Struggles</h4>
11+
<p>The hardest part of the project was figuring out how to give console access to members. Proxmox does not provide a friendly way to access their VNC consoles, so I had to dig into it to figure out how they did it and try to do a similar thing within Proxstar. Upon clicking the ‘Console’ button, Proxstar generates a valid token for the port that the noVNC session will be spun up on. It then forwards the port that the actual VNC session will be spun up on from the respective Proxmox host to the noVNC instance within Proxstar and starts the VNC session for the VM on Proxmox. Finally, Proxstar opens a new tab with the noVNC session and a valid token to access it. It isn’t the cleanest solution, but it has held up pretty well.</p>
12+
13+
<h5 id="feel-free-to-check-out-the-source-code-for-proxstar-here">Feel free to check out the source code for Proxstar <a href="https://github.com/com6056/proxstar">here</a>!</h5>
14+
:ET
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
I"�<p><a href="https://galenguyer.com/blog/2020/05/19/docker-rust-notpresent">Check out this post on Galen’s blog!</a></p>
2+
3+
<p>Today, a friend posted the following snippet in Slack:</p>
4+
<pre> [~/Documents/shelflife] [±docker✗] $ docker run -v -it --rm --name my-running-app shelflife-rust-docker
5+
Error: NotPresent</pre>
6+
<p>The first guess was that they had deleted the docker image and forgot to rebuild it. That wasn't the case, leading me to dive into this cryptic error message that we assumed was some hidden Rust or Docker error. We weren't able to find any example of this error message for Rust or Docker online, so I knew this would be a fun challenge.</p>
7+
8+
<p>The first thing I did was to make sure the path to the binary was working, as it'd be silly if this wasn't working because <code>/usr/local/bin</code> wasn't in the container's PATH. I changed the last line in the Dockerfile from <code>CMD ["shelflife"]</code> to <code>ENTRYPOINT ["/usr/local/bin/shelflife"]</code>. The error persisted, which meant it wasn't a PATH error. Of course this couldn't be easy.</p>
9+
10+
<p>The next step in diagnosis was to get a shell on the container. That would typically be done via <code>docker exec</code>, but that only works on a running container, which we didn't have. To get around this, I changed the last line of the Dockerfile to <code>ENTRYPOINT ["/bin/bash"]</code>, which makes <code>docker run -it</code> drop you into an interactive bash shell. This means I could easily see what was going on and run commands from inside the container.</p>
11+
12+
<p>Now that I had a shell, I navigated to <code>/usr/local/bin/</code> and ran <code>./shelflife</code> to check if there was any output docker was hiding. Unfortunately, there wasn't. I was at roughly the same place as when I started - a cryptic error message and no idea where it was coming from. At least now I was decently sure it wasn't not a docker issue.</p>
13+
14+
<p>I'd run into issues with dynamically linked libraries not being installed in the past, so I used <code>ldd</code> (List Dynamic Dependencies) to make sure all the dependencies existed. Everything looked fine, and I double-checked by manually installing the library packages for everything <code>ldd</code> said was linked. Everything was already installed, but the error persisted.</p>
15+
16+
<p>The last thing I tried was installing <code>strace</code>, a tool for tracing system calls, and running <code>strace ./shelflife</code>. This gave me a huge output full of system calls, but near the bottom was something that looked familiar, the text "NotPresent". Now I knew I was on the right path! The relevant output that got me to the final answer was the following:</p>
17+
18+
<pre>getcwd("/usr/local/bin", 512) = 15
19+
statx(0, NULL, AT_STATX_SYNC_AS_STAT, STATX_ALL, NULL) = -1 EFAULT (Bad address)
20+
statx(AT_FDCWD, "/usr/local/bin/.env", AT_STATX_SYNC_AS_STAT, STATX_ALL, 0x7ffc04639b10) = -1 ENOENT (No such file or directory)
21+
statx(AT_FDCWD, "/usr/local/.env", AT_STATX_SYNC_AS_STAT, STATX_ALL, 0x7ffc04639930) = -1 ENOENT (No such file or directory)
22+
statx(AT_FDCWD, "/usr/.env", AT_STATX_SYNC_AS_STAT, STATX_ALL, 0x7ffc04639750) = -1 ENOENT (No such file or directory)
23+
statx(AT_FDCWD, "/.env", AT_STATX_SYNC_AS_STAT, STATX_ALL, 0x7ffc04639570) = -1 ENOENT (No such file or directory)
24+
write(2, "Error: ", 7Error: ) = 7
25+
write(2, "NotPresent", 10NotPresent) = 10
26+
write(2, "\n", 1
27+
) = 1
28+
sigaltstack({ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=8192}, NULL) = 0
29+
munmap(0x7fb5000f2000, 8192) = 0
30+
exit_group(1) = ?
31+
+++ exited with 1 +++</pre>
32+
33+
<p>There it is! Right before exiting, there's several checks for a <code>.env</code> file that all fail. This error didn't happen when run locally, because my friend already made a <code>.env</code> file. However, I never created one, and more critically, the Dockerfile never copied their version of the file into the image. Once we created a <code>.env</code> file and added <code>COPY .env .</code> to the Dockerfile, it started as intended! This wasn't an issue with Docker or Rust at all, but a library giving an unhelpful error message. We couldn't find any documentation of this online, so I hope this post might serve to help anyone else who runs into this issue!</p>
34+
:ET
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
I"�<h1 id="summary">Summary</h1>
2+
<p><a href="https://github.com/zcy3071/CapsuleKiller">Capsule Killer</a> is a first-person shooter that I developed to learn more about the skills and
3+
processes involved with game development. Upon launching the game, the player will be met with a main menu that allows them to start a game,
4+
view the controls, or exit the game. When a player starts a game, they will spawn in the center of the map and enemies will begin spawning
5+
at random locations throughout the map every 2-5 seconds. The enemies move towards the player, doing damage upon collision with the player.
6+
The player has the ability to run away from and shoot enemies. The goal of the game is to defeat as many enemies as possible.</p>
7+
:ET
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
I"E<h1 id="summary">Summary</h1>
2+
<p>Smart shades is a web service that allows one to control their window shades using a website.
3+
The hardware requirement is a Raspberry Pi (connected to the Internet), a stepper motor, housing for the stepper motor (3D printed), a stepper motor driver (I used the Pololu A4988), a 10K ohm resistor, and a domain.
4+
The application uses Python, Flask, OpenShift in the back end, Bootstrap, JavaScript, and Ajax.
5+
In short, there are two Flask apps running, one on <a href="https://shades.csh.rit.edu">a CSH domain</a> and one on the Pi.
6+
The Flask app on the CSH website has the JavaScript and Ajax to make requests to the Flask app on the Pi, which can then take care of changing the window shades.</p>
7+
8+
<h1 id="the-story">The Story</h1>
9+
<p>I picked up this IOT project from R&amp;D.
10+
Spencer, our current R&amp;D director, had the hardware (stepper motor, housing for stepper motor, and the stepper motor driver) and asked if someone could do the software by ImagineRIT.
11+
I had some ideas for ImagineRIT, but this one seemed more fun than the rest of them.
12+
I went into this knowing how to code, specifically in Python, but not having a great understanding of how to incorporate the hardware with the software, including web application integration.
13+
I started the project by figuring out how to use RPi.GPIO library by making a simple program with LEDs.
14+
Then I started using the stepper motor driver and the stepper motor.
15+
This ended up being a hardware problem, not a software one.
16+
After countless hours I figured out that I can connect an LED to 2 of the 4 pins of the motor and if the LED lights up upon turning the motor then I have found a pair of wires.
17+
From there I had to figure out how stepper motors work in software, which comparatively was not that difficult.</p>
18+
19+
<p>The next part of this project was controlling the motor from a website.
20+
I started by reading about <strong>Flask</strong> and making a quick Hello world application on the IP on the Pi.
21+
Since Flask uses python, and so does my code for the shades, I was simply able to combine the two.
22+
I learned about <strong>HTML</strong> and <strong>bootstrap</strong> while creating the index page for this application.</p>
23+
24+
<p>I now needed a domain that people could type in, because remembering an IP address is only possible when you type it in countless times as the developer.
25+
Thankfully, our OpComm director, Steven, helped me out during the OpCommathon by showing me OpenShift.
26+
As soon as I ran it up, it crashed.
27+
Rpi.GPIO imports can only be run on a Raspberry Pi… I eventually decided to make a second Flask app that would simply run on the CSH domain and link to the IP of the Pi.
28+
This, however, was not ideal because every time you changed the height of the shade, the page would reload.
29+
That is neither pretty nor efficient.
30+
To make the matters worse, the link was to an IP address, and a real world application should not be pointing to an IP address.
31+
I asked around, and upon the suggestion of our financial director, Devin, I decided to implement <strong>Ajax</strong>.</p>
32+
33+
<p>I had never used JavaScript, nor Ajax prior to this, so it was a bit of learning curve.
34+
Obstacle one was making the script work; aside from syntax, it took a while to realize that script needed to be called after the buttons were created.
35+
Then came other obstacles, such as not being able to POST to Pi because it ran on HTTP and the website ran on HTTPS.
36+
Somewhere in there I had to implement CORS or Cross-Origin Resource Sharing, lack of it crashes the program.
37+
With the help of our chairman, Jordan, I was able to get the Flask application on the Pi running on HTTPS, thereby allowing communication between the CSH domain and the Pi.</p>
38+
39+
<p>I proceeded to add some more functionality to this application after OpCommathon.
40+
This took a couple day’s worth of work because I was still learning JavaScript.
41+
Now you can click buttons to set the height as a percentage, change how many steps or pulses the motor requires to make the shade go from completely down to completely up, and move the motor n steps at a time for debugging purposes.
42+
Furthermore, it shows the current shade percentage.
43+
The idea behind showing that information is that if it does not match up with what you have physically in front of you, then you will know that you need to change your values for the program.
44+
The best part is that the page does not reload upon calling a function, the two apps simply talk to each other.</p>
45+
46+
<p>Altogether, this project was a lot of fun.
47+
I learned quite a bit, both in the software world and hardware world.
48+
ImagineRIT is still weeks from now, and as a result I plan on adding Amazon Alexa Skill to this, or someway of using voice command to perform the same actions.</p>
49+
50+
<p>P.S. For details on wiring components, please visit the GitHub source of this project <a href="https://github.com/ag-ayush/smart-window-shades">here</a>.</p>
51+
:ET
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
I"><p><a href="https://github.com/sethgower/suds">SUDS</a>, or the Shower Use Detection System, shows the status of the showers in our dorm hall, which is located on the third floor of Nathaniel Rochester Hall. When someone is in the shower and the door is locked, an LED on a panel in the hall next to the bathroom illuminates. In addition to the LEDs outside of the bathroom, I will be creating a web app to track live status updates remotely, and potentially collect statistics on when the showers/stalls are most used.</p>
2+
3+
<p>SUDS is the first big hardware project that I have ever actually done, and the first time I have soldered my own board (outside of soldering headers onto MCUs and chips). The web app that I am going to build will be my first time using a MySQL database and creating a server-side backend that handles all of the input from the bathrooms.</p>
4+
5+
<p>SUDS is a project that was first created by CSHers a few years ago. It was originally a simple circuit driven by AA batteries, but my version runs on a Raspberry Pi.</p>
6+
7+
<p>SUDS is driven by a Raspberry Pi in the bathroom ceiling, which outputs 5V; for future versions I will be making the circuit draw 3.3V to decrease the brightness of the LEDs. The current then goes to a limit switch on the door lock which closes the circuit and illuminates the LED for that shower. The wiring diagrams can be found on the <a href="https://github.com/sethgower/suds">GitHub page</a>. On the proto-board, on the same row as the anode of the LED, there is a pulldown resistor that leads to the GPIO pin corresponding to that shower.</p>
8+
:ET

0 commit comments

Comments
 (0)