<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Chris Bensen on Medium]]></title>
        <description><![CDATA[Stories by Chris Bensen on Medium]]></description>
        <link>https://medium.com/@chrisbensen?source=rss-279db4a5cf86------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*uosgJ4B0CQ6X9FjDC8gvWg.jpeg</url>
            <title>Stories by Chris Bensen on Medium</title>
            <link>https://medium.com/@chrisbensen?source=rss-279db4a5cf86------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 23:31:30 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@chrisbensen/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Raspberry Pi PoE HAT Fan Noise]]></title>
            <link>https://chrisbensen.medium.com/raspberry-pi-poe-hat-fan-noise-669b36fd0cda?source=rss-279db4a5cf86------2</link>
            <guid isPermaLink="false">https://medium.com/p/669b36fd0cda</guid>
            <category><![CDATA[poe-hat]]></category>
            <category><![CDATA[raspbery-pi]]></category>
            <category><![CDATA[poe]]></category>
            <category><![CDATA[hats]]></category>
            <dc:creator><![CDATA[Chris Bensen]]></dc:creator>
            <pubDate>Sun, 28 May 2023 21:28:54 GMT</pubDate>
            <atom:updated>2023-05-28T21:28:54.037Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*NDmOq4BHbBRjfi507BEo0Q.jpeg" /></figure><p>The latest Raspberry Pi PoE HAT on a Pi 4 is awesome! One cable to the right switch and you’ve got power and internet. One runs Homebridge giving Apple Home access to Ubiquity cameras, the Nest, and a few other custom things. It’s a great combination, the only thing I need to do is put Homebridge into docker and put the configure script into GitHub in case things fail. But there is one glaring issue with the PoE HAT. The fan. It’s loud! Very very very loud. It sounds like a basketball mosquito every 30 seconds. At 104°F (40°C) the fan turns on until the temperature is 102.2°F (39°C). It. does. this. all. day. and. night. long.</p><p>The solution is fortunately simple:</p><ol><li>Shutdown your Pi.</li><li>Mount the SD card.</li><li>Open the file: <em>/boot/config.txt</em></li></ol><p>4. At the beginning of the file add the following:</p><pre># PoE HAT Fan Speeds<br>dtparam=poe_fan_temp0=55000<br>dtparam=poe_fan_temp1=60000<br>dtparam=poe_fan_temp2=65000<br>dtparam=poe_fan_temp3=70000</pre><p>5. Plug the SD card back into your Pi and enjoy</p><p>My fan goes on at 55°C, increases again at 60°C, again at 65°C and full speed at 70°C. You can use the command to check the temperature and tweak the values above according to your environment.</p><pre>vcgencmd measure_temp</pre><p>I do think I need a good heat sink and chances are you do as well. But most heat sinks use a sticker which acts as a thermal insulator. You want thermal paste but then it’s difficult to hold it to the Pi, but this will be a discussion for a future post.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=669b36fd0cda" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Happy Pi Day — Win a Free Raspberry Pi 4]]></title>
            <link>https://chrisbensen.medium.com/happy-pi-day-win-a-free-raspberry-pi-4-566bc6bf3de7?source=rss-279db4a5cf86------2</link>
            <guid isPermaLink="false">https://medium.com/p/566bc6bf3de7</guid>
            <category><![CDATA[pi-day]]></category>
            <category><![CDATA[raspberry-pi]]></category>
            <category><![CDATA[pi]]></category>
            <dc:creator><![CDATA[Chris Bensen]]></dc:creator>
            <pubDate>Tue, 14 Mar 2023 23:44:51 GMT</pubDate>
            <atom:updated>2023-03-14T23:45:08.575Z</atom:updated>
            <content:encoded><![CDATA[<h3>Happy Pi Day — Win a Free Raspberry Pi 4</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KDgZt16rK8p_IGlGlAmLgw.png" /></figure><p>I’m blamed for causing the Raspberry Pi shortage because I built the World’s Largest Raspberry Pi Cluster with 1050 Raspberry Pi 3B+. In my defense I didn’t, all Pi were purchased in February 2019, you can read all about it <a href="https://medium.com/oracledevs/a-temporal-history-of-the-worlds-largest-raspberry-pi-cluster-that-we-know-of-4e4b1e214bdd">here</a>. But in March 2020 I had some time to kill as most of us did and there were some deals on Pi 4 so I picked a bunch up. Not 1,000 of them, but a healthy stockpile.</p><p>So today, because there are a lot of people without and I have I am giving away one Raspberry Pi 4B+ with 4gb of RAM and one SD card. To enter the raffle, follow these steps and watch the video below:</p><ol><li>Subscribe to this video</li><li>Like this video</li><li>Comment on this video with what you will do with the Pi</li><li>4. Send an email to <strong>thegreatraspberrypigiveaway@gmail.com</strong> and in the email include the username you commented with so I can verify you are subscribed, liked the video and commented.</li></ol><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FyUFrinL0Wp8%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DyUFrinL0Wp8&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FyUFrinL0Wp8%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/4569f88e0e0408e9f4411c7d261fe518/href">https://medium.com/media/4569f88e0e0408e9f4411c7d261fe518/href</a></iframe><p>The drawing will end on noon Pacific Standard Time March 19th and a video will be posted on March 20th announcing the winner. You will receive an email to get your address and badabing badaboom, you get a Pi. The Pi and SD card are free to the person randomly picked that follows the directions above and shipping will be paid for to the lower 48 United States. If you are somewhere else on the planet you will pay shipping and customs. I’ll ask you to send me a shipping label.</p><h3>Happy Pi Day!</h3><p>This is the first of many new videos where I will build cool projects. For example, here is the last Christmas ornament I made.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FqO0IztNJMl8%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DqO0IztNJMl8&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FqO0IztNJMl8%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/707d1834a44f6285cbc9345cffb1341d/href">https://medium.com/media/707d1834a44f6285cbc9345cffb1341d/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=566bc6bf3de7" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Christmas Special 2022 — The World’s Smallest Raspberry Pi Cluster]]></title>
            <link>https://chrisbensen.medium.com/christmas-special-2022-the-worlds-smallest-raspberry-pi-cluster-e4e972ba71fb?source=rss-279db4a5cf86------2</link>
            <guid isPermaLink="false">https://medium.com/p/e4e972ba71fb</guid>
            <category><![CDATA[cluster]]></category>
            <category><![CDATA[christmas]]></category>
            <category><![CDATA[raspberry-pi]]></category>
            <category><![CDATA[tardis]]></category>
            <category><![CDATA[ornaments]]></category>
            <dc:creator><![CDATA[Chris Bensen]]></dc:creator>
            <pubDate>Fri, 23 Dec 2022 19:20:34 GMT</pubDate>
            <atom:updated>2022-12-23T19:20:34.354Z</atom:updated>
            <content:encoded><![CDATA[<h3>Christmas Special 2022 — The World’s Smallest Raspberry Pi Cluster</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*57UXFXQ4bRvvAbWrPb0CiQ.jpeg" /></figure><p>A few years back I created a Death Star ornament which started a tradition of wanting to make an ornament each year. It’s been a few years but here is my second ornament in my collection, the World’s Smallest Raspberry Pi Cluster.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*57UXFXQ4bRvvAbWrPb0CiQ.jpeg" /></figure><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FqO0IztNJMl8%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DqO0IztNJMl8&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FqO0IztNJMl8%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/707d1834a44f6285cbc9345cffb1341d/href">https://medium.com/media/707d1834a44f6285cbc9345cffb1341d/href</a></iframe><p>This mini Raspberry Pi cluster is the smallest Raspberry Pi cluster in the world. Also the most powerful ornament in the world. What’s it do, that’s a good question. Right now it runs the same software I ran on the World’s Largest Raspberry Pi Cluster so watch the video and find out and comment what I should run on it.</p><p>If you want to make your own, go get the STL files on <a href="https://www.thingiverse.com/thing:5738425">Thingiverse</a>.</p><p>If you are interested in the Death Star ornament here is a video or you can make it by getting the STL files on <a href="https://www.thingiverse.com/thing:2740805">Thingiverse</a>.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FmqZPGJ9x3TQ%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DmqZPGJ9x3TQ&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FmqZPGJ9x3TQ%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/ecc7850c20ae0802aeb1d802df07dc86/href">https://medium.com/media/ecc7850c20ae0802aeb1d802df07dc86/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e4e972ba71fb" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Raspberry Pi Super Computer at Java One 2022]]></title>
            <link>https://medium.com/oracledevs/the-raspberry-pi-super-computer-in-devnucleus-at-cloud-world-2022-2d24208d1712?source=rss-279db4a5cf86------2</link>
            <guid isPermaLink="false">https://medium.com/p/2d24208d1712</guid>
            <category><![CDATA[graalvm]]></category>
            <category><![CDATA[raspberry-pi]]></category>
            <category><![CDATA[cloudworld]]></category>
            <category><![CDATA[oracle-cloud]]></category>
            <category><![CDATA[worlds-largest]]></category>
            <dc:creator><![CDATA[Chris Bensen]]></dc:creator>
            <pubDate>Tue, 18 Oct 2022 01:58:48 GMT</pubDate>
            <atom:updated>2022-12-20T01:38:33.805Z</atom:updated>
            <content:encoded><![CDATA[<p>by <a href="https://twitter.com/chrisbensen">Chris Bensen</a></p><p>If you prefer you can read this blog post on GitHub <a href="https://github.com/chrisbensen/chris-blogs/blob/main/%CF%80Cluster/CloudWorld2022/CloudWorld-DevNucleus2022.md">here</a>.</p><p>The Raspberry Pi Super Computer was originally built for Oracle Open World in October 2019. There are 1050 Raspberry Pi 3b+ in four server racks configured in a big square box reminiscent of a British police box popularized in a certain BBC TV series. Fast forward to today, and The Raspberry Pi Super Computer <em>(Pi Cluster)</em> was sent to e-waste, some parts stripped off it, and sat dormant for two years until May of this year, when it found its way to my garage for a complete overhaul.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4veoQ9l84Oop2dOwStP4Yg.jpeg" /><figcaption>Raspberry Pi Super Computer at Open World 2019</figcaption></figure><p>For a temporal history of how 1050 Raspberry Pi came to be, you can read <a href="https://medium.com/chrisbensen/a-temporal-history-of-the-worlds-largest-raspberry-pi-cluster-that-we-know-of-4e4b1e214bdd">A Temporal History of The World’s Largest Raspberry Pi Cluster</a>.</p><p>It begins with Gerald Venzl at Oracle Switzerland bringing the 12-node cluster to my attention, then we brainstormed a big cluster with Stephen Chin. Learn how the Pi Cluster went to e-waste during COVID lockdowns and the California fires and how Eric Sedlar rescued it, eventually storing it at Oracle Labs. If you find that too long, watch the original build video of <a href="https://www.youtube.com/watch?v=KbVcRQQ9PNw">The World’s Largest Raspberry Pi Cluster that we know of</a>, this <a href="https://blogs.oracle.com/developers/post/building-the-worlds-largest-raspberry-pi-cluster">Building the world’s largest Raspberry Pi cluster</a> by Gerald Venzl, and this video of the <a href="https://www.youtube.com/watch?v=ELvkg_88XSY">Big Pi Cluster In My Garage — Part I</a>.</p><p>And by the way, if you’re reading this, there’s a high likelihood that you’d ‘be a great Luminary. What’s a Luminary? It’s our recently launched developer group that connects developers like you to exclusive technical content, free swag, and a community to help you build something as cool as this cluster, <a href="https://go.oracle.com/luminaries">become a Luminary today</a>.</p><h4>Resurrection</h4><p>When CloudWorld was announced we immediately proposed to resurrect The World’s Largest Raspberry Pi Super Computer <em>(that we know of)</em>. Who doesn’t like a good resurrection story? The proposals went something like this:</p><p>1. Donate it to the Computer History Museum as a non-functional art piece for Pi-Day.<br>2. Raspberry Pi’s are valuable now. Raffle off a piece of the Pi to win a free Raspberry Pi 3B+ from one of the World’s Largest Raspberry Pi Clusters.<br>3. We have one opportunity to make history. We fix it for CloudWorld, add fans so it doesn’t overheat, and run it as an “on prem” and “edge” device showing off tech that is being built in the labs. We’ll include <a href="https://www.oracle.com/java/graalvm/?source=:ex:tb:::::RC_WWMK220210P00062:Medium_CBensen_Pi_DevNucleaus&amp;SC=:ex:tb:::::RC_WWMK220210P00062:Medium_CBensen_Pi_DevNucleaus&amp;pcode=WWMK220210P00062">GraalPython</a>, <a href="https://www.oracle.com/java/?source=:ex:tb:::::RC_WWMK220210P00062:Medium_CBensen_Pi_DevNucleaus&amp;SC=:ex:tb:::::RC_WWMK220210P00062:Medium_CBensen_Pi_DevNucleaus&amp;pcode=WWMK220210P00062">Java</a> and <a href="https://www.oracle.com/linux/?source=:ex:tb:::::RC_WWMK220210P00062:Medium_CBensen_Pi_DevNucleaus&amp;SC=:ex:tb:::::RC_WWMK220210P00062:Medium_CBensen_Pi_DevNucleaus&amp;pcode=WWMK220210P00062">Oracle Linux 9</a> running on every device on the Pi Cluster. It’s all connected to <a href="https://www.oracle.com/cloud/?source=:ex:tb:::::RC_WWMK220210P00062:Medium_CBensen_Pi_DevNucleaus&amp;SC=:ex:tb:::::RC_WWMK220210P00062:Medium_CBensen_Pi_DevNucleaus&amp;pcode=WWMK220210P00062">Oracle Cloud Infrastructure (OCI)</a> through Site-to-Site <em>(scroll to the bottom for directions on this)</em> VPN for on prem and via micro-services, compute instances, Autonomous Database, Services Gateway, and Load Balancer. AR visualizations would be ideal, and we could run something cool on it — like when we ran SETI@home on the Raspberry Pi Mini Super Computer, an 84-Pi Cluster. I came up with the idea to set up a service so anyone in the world could send code to the cluster to run a workload, as we show off our Digital Twin AR/VR services and create blogs and videos to inspire developers and students. We can show people why developers and students are having a lot of fun learning and using <a href="https://www.oracle.com/cloud/free/?source=:ex:tb:::::RC_WWMK220309P00059:Medium_CBensen&amp;SC=:ex:tb:::::RC_WWMK220309P00059:Medium_CBensen&amp;pcode=WWMK220309P00059">Oracle’s Free Tier</a>. Plus, we can get a Guinness Book world record.</p><p>We choose option three and the search for a new lab began. I spoke with the leadership of various product teams mentioned above, as well as leaders in the Raspberry Pi community like <a href="https://twitter.com/geerlingguy">Jeff Geerling</a> and Eben Upton, and laid out a plan. I can’t tell you about the entire plan because we’ve just set the foundation for it, but there’s a much more to come. This is just the story of getting the Pi Cluster to DevNucleus at CloudWorld and a brief mention of what happens after. It turns out a Guinness Book adjudication is really expensive!</p><p>The first step was to identify a budget and an estimate of the work to see if it was feasible. We knew we needed:</p><p>1. Fans. Lots of fans.<br>2. To replace any parts missing.<br>3. To test everything out.<br>4. To write new software.</p><p>Every Pi network boots. In 2019 I had Oracle Linux 7 running on the entire cluster, but did it still work? Did we have all the source code, MAC addresses, and everything needed to do it again?</p><p>The second step was to get a place to work on the Pi Cluster. Try finding a place with double doors, close to a freight elevator, with enough power and space to work on it, and a network that isn’t locked down tight — not easy! I looked at Oracle facilities around the world. The logistics of working on something like this remotely and all the physical work that would have to be put into it meant anywhere in the world would work only if certain requirements were met. I’d have to travel there, set everything up, and have a dozen people to help. We’d set it up for remote access but someone would have to be available in person when things didn’t work right. After a nice lunch with my amazing wife, we decided our garage worked the best, and that’s where <a href="https://twitter.com/search?q=%23BigPiClusterInMyGarage&amp;src=typed_query">#BigPiClusterInMyGarage</a> started.</p><h4>Adding Fans — Cooling the Raspberry Pi</h4><p>Once it was delivered, I went to work ensuring our budget was accurate, then rectifying and testing things while ordering replacement parts (mostly fans). Lots of fans: 250 new fans to be exact. The cluster ended up with 257 fans and that isn’t counting the fans that are in each of the switches, the server, or the power supplies. This required that I disassemble the entire cluster and reassemble it. Not every bolt was removed, but all 21 Pi 2U banks were disassembled, every 5th Pi removed and replaced, which meant 250 new Pi caddies with brackets for fans had to be printed. You can learn about that <a href="https://www.thingiverse.com/thing:3958586">here</a>. <a href="https://twitter.com/superpixels">Victor Agreda</a> used his newly purchased Ultimaker S5 to print a few dozen of the fan version of the caddies. The fans all needed power, and many thanks to <a href="https://twitter.com/ThatEliGuyatOCI">Eli Schilling</a> for creating many of the wiring harnesses. In addition, we added some easter eggs. I know it isn’t much of an easter egg if I tell the world about it, but I’ll explain it in more detail in the Warble section below (because it’s too cool to not say anything). I have a few videos documenting some of the work that can be found in <a href="https://medium.com/chrisbensen/a-temporal-history-of-the-worlds-largest-raspberry-pi-cluster-that-we-know-of-4e4b1e214bdd">A Temporal History of The World’s Largest Raspberry Pi Cluster</a>.</p><h4>Operating System — The Smartest Operating System Around</h4><p>I think a lot of us underestimate the value of a good operating system when building out infrastructure and hardware, and Oracle Linux is top notch. I go into more detail about the operating system in <a href="https://medium.com/chrisbensen/a-temporal-history-of-the-worlds-largest-raspberry-pi-cluster-that-we-know-of-4e4b1e214bdd">A Temporal History of The World’s Largest Raspberry Pi Cluster</a> <em>(and I have some other stuff I’m working on so you can set up network booting Pi at home). </em>Because we had all that work to build upon, we had to upgrade from Oracle Linux 7 to Oracle Linux 9. I’ll tell you a secret: it wasn’t that simple. Nevertheless, the Oracle Linux team has been amazing to work with and really deserves all the credit for setting up the operating system for the Pi Cluster. Go check out Oracle Linux 9, it’s worth using or upgrading to. There were a few hiccups, such as the added layer of security which meant the root account no longer had SSH access by default.</p><p>It’s worth mentioning here how we boot the Pi. Every Pi in the cluster is network booting off a single, read-only NFS mount on the server, and we added a systemd service to run a bash script whenever the server or Pi boots up. This makes configuring what we run almost effortless.</p><h4>Software and Cloud Services — GraalVM is Fast Running on Client or in the Cloud</h4><p>All the software is open source and can be found <a href="https://github.com/oracle-devrel/picluster">here</a> in our DevRel GitHub repository. There are some things coming from the labs and aren’t available even as a tech preview <em>(I tried, they just weren’t ready)</em> so those aren’t included. Be warned, most of that code was written quickly. What you find might not make a whole lot of sense, so let me explain.</p><p>First, there’s the software on the cluster. The server runs a Docker container comprised of GraalPython on top of <a href="https://www.oracle.com/java/graalvm/?source=:ex:tb:::::RC_WWMK220210P00062:Medium_CBensen_Pi_DevNucleaus&amp;SC=:ex:tb:::::RC_WWMK220210P00062:Medium_CBensen_Pi_DevNucleaus&amp;pcode=WWMK220210P00062">GraalVM</a>. That <strong>Dockerfile</strong> is undergoing continuous improvement so I don’t recommend copying it just yet. I’ve provided some bug reports, but as soon as the Graal environment variables and CTRL+C work <em>(and maybe a new image for GraalPython is created)</em> you’ll want to dive right in. Meanwhile, know that this is one way of doing it. I’ve seen about an <a href="https://www.graalvm.org/python/">8x increase in performance when running pure Python code under GraalVM</a>. That’s pretty impressive!</p><p>Every device on the cluster runs a web service. The server broadcasts a UDP message with its IP address and port for any device to listen to and communicates with the server for auto discovery. This is new from previous years where the server’s IP address was put into an environment variable. The IP address doesn’t change so we could hard code it, but there were two issues: Anyone working on this needs to run a test system with their desktop and a simulation of a Pi or a couple of Pis on their desk, and the environment variables are lost once you sudo. This actually solves a lot of issues! Once a Pi boots up it runs its web server, listens for the UDP message, registers its IP address and MAC address with the server, and listens for work. At intervals, the server will send a ping to each Pi as a health check to make sure they should be in the list of available Pi.</p><p>Every five seconds each Pi sends all its data <em>(CPU, memory, temperature, etc.)</em> to a REST endpoint on an Autonomous Database via the native ORDS support. The documenation can be found <a href="https://docs.oracle.com/en/cloud/paas/autonomous-database/adbsa/ords-autonomous-database.html#GUID-E2E921FF-2D80-4E32-9660-28506D10BADB">here</a>. I put some code in where if the Pi fail to send their data, it waits a little longer the next time, scaling up to 60 seconds. It turns out to be a mountain of data which Autonomous Database handles effortlessly. I tried a few other databases that shall not be named and let’s just say they couldn’t handle it, sometimes resulting in delays greater than five seconds.</p><h4>Digital Twin with AR/VR — Visualize your Data</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Sv542XDZr-bURwmGIqKX5g.png" /><figcaption>Raspberry Pi Super Computer Rendering</figcaption></figure><p>I created a fairly detailed 3D model of the Pi Cluster that can be found <a href="https://github.com/oracle-devrel/picluster/tree/main/models">here</a> and opened in your favorite 3D program. Our AR/VR and cloud experts <a href="https://twitter.com/Vojtech_WW">Wojciech Pluta</a>, <a href="https://www.linkedin.com/in/victormartindeveloper">Victor Martin</a>, <a href="https://twitter.com/bogdanfarca">Bogdan Farca</a> and <a href="https://www.linkedin.com/in/sjcoggins/">Stuart Coggins</a> went to work building some amazing AR and VR experiences. They tuned databases, wrote APEX apps, and ran socket.io for streaming. They leveraged a Kubernettes cluster called <a href="https://docs.oracle.com/en-us/iaas/Content/ContEng/Concepts/contengoverview.htm">OCI OKE</a> so the 3D experiences can scale without falling over, which means anyone can put a Digital Twin of the Pi Cluster in their living room. We have iPads for AR and printed QR codes so the iPad can track the cluster with millimeter accuracy, enabling attendees to view the goings-on of the cluster interactively. The team also built a Meta VR version, the details of which will be revealed soon. There wasn’t enough power to run the entire cluster in my garage so we’ll be integrating this and testing it before the doors open at CloudWorld. It may work, it may fall over. Whatever happens, it will be a good story! I’ll add a link here when we have something written on AR/VR Digital Twin.</p><h4>OCI Services — At the Center of Every Project is Cloud Infrastructure</h4><p>In my garage, the Pi Cluster is setup as an “on prem” server. I created an isolated subnet on my Ubiquity Dream Machine Pro, configured a site-to-site VPN to OCI using a <a href="https://www.oracle.com/security/cloud-security/bastion/?source=:ex:tb:::::RC_WWMK220210P00062:Medium_CBensen_Pi_DevNucleaus&amp;SC=:ex:tb:::::RC_WWMK220210P00062:Medium_CBensen_Pi_DevNucleaus&amp;pcode=WWMK220210P00062">Bastion</a>, and used a local jump box that has two network interfaces <em>(one for the Pi Cluster subnet and one for the Pi Cluster)</em>. Thus, the Pi Cluster appears to the outside world as one IP address. Show up, plug in network power, and you’re good. I wish setup were that easy and I didn’t have to test everything — making sure cables didn’t bounce out of position — but let’s just say it’s that easy because it sounds more fun.</p><p>We won’t have control of the network at CloudWorld, so the Pi Cluster is an “edge device.” It uses cloud services such as <a href="https://docs.oracle.com/en-us/iaas/Content/Network/Tasks/servicegateway.htm">Services Gateway</a>, <a href="https://docs.oracle.com/en-us/iaas/Content/Balance/Concepts/balanceoverview.htm">Load Balancer</a>, and <a href="https://docs.oracle.com/en-us/iaas/Content/GSG/Concepts/managing_your_domains.htm">Domain Management</a>. Yes, we have a domain. I’ll get to that in the next section.</p><p>The network looks like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LT2Fs_Gl0lb8LXpAaXL8DA.png" /><figcaption>Pi Cluster Demonstration Network Diagram</figcaption></figure><p>If you have any questions about this head over to Oracle’s public <a href="https://bit.ly/odevrel_slack">Slack channel</a> for developers. Ask any question you want. How to set it up, what services to use. You’ll find your answers there!</p><h4>IoT — Specific Lightweight Tasks with Small Inexpensive Microcontrollers</h4><p>We also have a pair of Arduinos running on the cluster. The first Arduino is an Arduino Mega with an Ethernet HAT. The original code can be found <a href="https://github.com/oracle-devrel/picluster/tree/main/source/arduino/ServerSwitch">here</a>. It runs a web service and turns on two solenoids for remote access to the physical reset and power buttons on the server. I’ve changed the software a bit compared to the repository and didn’t publish yet, so I left this older version up. The version I haven’t published registers itself and waits for a simple startup command when a developer SSHs into the Bastion.</p><p>The second Arduino is the same hardware but runs a REST server listening for a JSON payload and is connected to a dozen <a href="https://www.adafruit.com/product/1426">NeoPixels</a> in the light at the top of the police box.</p><h4>Warble — A Custom Programming Language Designed for the Pi Cluster</h4><p>We’re hosting the domain <a href="https://warble.withoracle.cloud/code">https://warble.withoracle.cloud</a> on OCI, backed by <a href="https://docs.oracle.com/en-us/iaas/Content/GSG/Concepts/managing_your_domains.htm">Domain Management</a>, a <a href="https://docs.oracle.com/en-us/iaas/Content/Balance/Concepts/balanceoverview.htm">Load Balancer</a>, and a <a href="https://www.oracle.com/cloud/compute/?source=:ex:tb:::::RC_WWMK220210P00062:Medium_CBensen_Pi_DevNucleaus&amp;SC=:ex:tb:::::RC_WWMK220210P00062:Medium_CBensen_Pi_DevNucleaus&amp;pcode=WWMK220210P00062">Compute Instance</a>. The compute instance is running the same software that is running on the Pi Cluster: A Docker Container with GraalPython and a web service. This isn’t quite ready for prime time but check back here or on Twitter October 18th–20th because it will be live during CloudWorld, and I think it’ll be a lot of fun.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YxAmPwwUU5Hr0o8jHb4GgQ.png" /><figcaption>Warble Logo</figcaption></figure><p>We’ve created a programming language designed for Twitter to be run on the Pi Cluster called <a href="https://github.com/oracle-devrel/picluster/tree/main/source/warble">Warble</a>. Warble isn’t a full-featured programming language and I took a lot of shortcuts. It’s made to use as few characters as possible so you can post a Warble to Twitter and have it run on the Pi Cluster. I have a Python script running on a Computer Instance using the Twitter API to search for the hashtag <strong>#pi</strong>. If the next character is an open curly brace and the last character is a close curly brace, then we have a Warble and it’s stored into a database. For Example:</p><pre>&gt; #pi{PRINT(“hello cluster”)}<br>&lt; hello cluster</pre><p>When the server has a few spare cycles, it gets a batch of Warbles from the database, finds a Pi that has lower than 30% CPU utilization, and sends the Warble to that Pi for processing. Warble is written in Python and converts Warbles into Python, then executes them. Currently it uses Python3, but we have a version written in GraalPython using some cutting-edge tech not ready for the public. Right now, our research engineers <a href="https://twitter.com/__rodrigobruno">Rodrigo Bruno</a> and <a href="https://www.linkedin.com/in/serhiiivanenko">Serhii Ivanenko</a> in Oracle Labs are getting it ready to run on the cluster. For now, the results from the Warble post to an Autonomous Database via a REST API that’s easy to set up. <a href="https://www.linkedin.com/in/sjcoggins/">Stuart Coggins</a> and <a href="https://twitter.com/thatjeffsmith">Jeff Smith</a> have been gracious enough to help with that and make sure it is rock solid. We’ll have an <a href="https://apex.oracle.com/en/">APEX</a> app that will display the Warbles and their results, and I hope we can get a leader board for custom visualizations.</p><p>Wouldn’t it be cool to see who can calculate Pi to the most digits on one of the World’s Largest Raspberry Pi Clusters?</p><pre>&gt; #pi{PRINT(2*ROUND(ACOS(0.0),3))}<br>&lt; 3.142</pre><p>It’s close enough.</p><p>Twitter will be a lot of fun, though it throttles the API and this is why we have the hosted domain. I will provide a REST endpoint to post Warbles. Maybe someone will figure out how to calculate Pi with <a href="https://en.wikipedia.org/wiki/Bailey%E2%80%93Borwein%E2%80%93Plouffe_formula">Bailey–Borwein–Plouffe_formula</a> using Warble or some other way.</p><p>I’m not going to write a syntax grammar but I will give some examples.</p><p>Warble supports variables:</p><pre>&gt; #pi{x=0PRINT(x)}<br>&lt; 0</pre><p>Warble can handle complex expressions:</p><pre>&gt; #pi{x=1/16.0²*(4.0/(8*k+1)-2.0/(8*k+4)-1.0/(8*k+5)-1.0/(8*k+6)}<br>&lt;</pre><p>While loops:</p><pre>&gt; #pi{i=0;WHILE(i&lt;10){PRINT(i);i++}}<br>&lt; 0<br>&lt; 1<br>&lt; 2<br>&lt; 3<br>&lt; 4<br>&lt; 5<br>&lt; 6<br>&lt; 7<br>&lt; 8<br>&lt; 9</pre><p>For loops:</p><pre>&gt; #pi{FOR(i=0;i&lt;10;i++){PRINT(i)}}<br>&lt; 0<br>&lt; 1<br>&lt; 2<br>&lt; 3<br>&lt; 4<br>&lt; 5<br>&lt; 6<br>&lt; 7<br>&lt; 8<br>&lt; 9</pre><p>I’m exposing most of the math functions as well as <strong>SETPRECISION(x)</strong>. It isn’t short on characters but that’s fine.</p><p>Plus, you can save values and load them again. They are user specific:</p><pre>&gt; #pi{SAVE(“pi”,1)}<br>&lt;</pre><p>and then follow it up with a load:</p><pre>&gt; #pi{x=LOAD(“pi”);x++;SAVE(“pi”,x);PRINT(x)}<br>&lt; 2</pre><p>Lastly, the easter eggs. Warble can play a sound. Yes, this is another IoT device hooked up to the cluster, but it’s a Pi with an amplifier! Unfortunately you can only hear it if you are standing in front of it. Makes you want to come to Las Vegas and attend CloudWorld, doesn’t it?</p><pre>&gt; #pi{PLAYSOUND(”<a href="http://downloads.bbc.co.uk/doctorwho/sounds/tardis.mp3///">http://downloads.bbc.co.uk/doctorwho/sounds/tardis.mp3</a>&quot;);}<br>&lt;</pre><p>There are also lights. This turns the first light to red:</p><pre>&gt; #pi{LIGHTS(0,255,0,0)}<br>&lt;</pre><p>If you wanted to turn the last light green you’d do this:</p><pre>&gt; #pi{LIGHTS(23,0,255,0)}<br>&lt;</pre><p>If you wanted to change the color of a light with a delay between do this:</p><pre>&gt; #pi{LIGHTS(0,0,255,0);SLEEP(20);LIGHTS(0,0,255,0)}<br>&lt;</pre><p>Or combine a few of these:</p><pre>&gt; #pi{FOR(i=0;i&lt;24;i++){LIGHTS(i,0,255,0)}SLEEP(20);FOR(i=0;i&lt;24;i++){LIGHTS(i,0,0,255)}}<br>&lt;</pre><h4>Setting up a Site-To-Site VPN with OCI</h4><p>On the Ubiquity Dream Machine Pro, with the help of <a href="https://www.linkedin.com/in/timothy-clegg">Tim Clegg</a>, I created a new subnet. Here’s an outline of the steps we followed. I’m not going to provide specific screen captures or a video because the options on Ubiquity and Oracle Cloud will change. Instead, here are some highlights of what you need and what to do:</p><p>Under networks create a new network with a name, I choose “pi”.<br>VLAN ID: 3<br>Network Type: Standard</p><p>Create a Site-to-site VPN<br>Network Name: pivpn<br>Pre-shared Key: ***********************<br>Server Address: &lt;IP Address of Router&gt; (default should be fine)<br>Remote Gateway/Subnets: 10.0.0.0/24<br>Remote IP Address: &lt;IP Address of remote VPN&gt;<br>Advanced: Manual<br>IPsec Profile: Customized<br>Route Distance: 30<br>Key Exchange Version: IKEv1<br>Encryption: AES-256<br>Hash: SHA1<br>IKE DH Group: 5<br>ESP DH Group: 5<br>Perfect Forward Secrecy: enabled<br>Dynamic Routing: enabled</p><p>I created three firewall rules:</p><p>1. pi block 192.168.3.1 (gateway)</p><p>Type: LAN Local<br>Action: Drop<br>Source, Souce Type: Network<br>Source, Network: pi<br>Destination, Source Type: Network<br>Destination, Network: pi<br>Destination, Network Type: Gateway IP Address</p><p>2. Default accept to pi</p><p>Type: LAN In<br>Action: Accept<br>Source, Souce Type: Network<br>Source, Network: Default<br>Destination, Source Type: Network<br>Destination, Network: pi</p><p>3. pi block to Default</p><p>Type: LAN Out<br>Action: Drop<br>Source, Souce Type: Network<br>Destination, Network: pi<br>Destination, Source Type: Network<br>Source, Network: Default<br>Advanced: Manual<br>Check Match State New<br>Check Match State Invalid</p><p>4. In OCI go to Networking and Site-to-Site VPN<br>Create IPSec Connection.<br>Give it a name.<br>You’ll want this to get your public IP address.</p><pre>dig -4 TXT +short o-o.myaddr.l.google.com <a href="http://twitter.com/ns1">@ns1</a>.google.com</pre><p>Enter it.</p><p>You’ll need to create two tunnels, so I set up both to point to the same VPN as OCI requires two and I only exposed one on my network. You’ll add this to the VPN.</p><p>5. Setup a Dynamic Routing Gateway<br>6. Setup a VCN, add an Ingress Rule with the CIDR that is your local subnet, for example mine is 192.168.3.0/24.</p><h4>The Future</h4><p>After going through the paces for DevNucleus at Oracle CloudWorld, the Pi Cluster is heading to Oracle Labs where… well, the next part is a bit of a secret for now. Potential uses include:<br>1. running additional tests for GraalVM and Java<br>2. Edge computing projects<br>3. Robots &amp; Parallel Processing (i.e. neural networks)<br>5. Activities suggested to us by you, the developer</p><p>With Pi Day 2023 just around the corner, you will definitely want to stay tuned for the next stage of evolution for this incredible piece of tech. Who knows? A few of the Pi may even find their way out of the cluster and into your hands.</p><p>I want to thank everyone that has had a hand in the project. Read <a href="https://medium.com/chrisbensen/a-temporal-history-of-the-worlds-largest-raspberry-pi-cluster-that-we-know-of-4e4b1e214bdd">A Temporal History of The World’s Largest Raspberry Pi Cluster</a> for how this crazy amazing project came to be.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2d24208d1712" width="1" height="1" alt=""><hr><p><a href="https://medium.com/oracledevs/the-raspberry-pi-super-computer-in-devnucleus-at-cloud-world-2022-2d24208d1712">The Raspberry Pi Super Computer at Java One 2022</a> was originally published in <a href="https://medium.com/oracledevs">Oracle Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A Temporal History of The World’s Largest Raspberry Pi Cluster (that we know of)]]></title>
            <link>https://medium.com/oracledevs/a-temporal-history-of-the-worlds-largest-raspberry-pi-cluster-that-we-know-of-4e4b1e214bdd?source=rss-279db4a5cf86------2</link>
            <guid isPermaLink="false">https://medium.com/p/4e4b1e214bdd</guid>
            <category><![CDATA[pi]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[raspberry-pi]]></category>
            <category><![CDATA[worlds-largest-pi-cluster]]></category>
            <category><![CDATA[network-boot]]></category>
            <dc:creator><![CDATA[Chris Bensen]]></dc:creator>
            <pubDate>Mon, 10 Oct 2022 23:56:07 GMT</pubDate>
            <atom:updated>2022-10-13T15:50:21.207Z</atom:updated>
            <content:encoded><![CDATA[<p>by <a href="https://twitter.com/chrisbensen">Chris Bensen</a></p><p>If you prefer you can read this blog post on GitHub <a href="https://github.com/chrisbensen/chris-blogs/blob/main/%CF%80Cluster/History/PiClusterHistory.md">here</a>.</p><p>The Raspberry Pi Super Computer was originally built for Open World in October 2019. We have 1050 Raspberry Pi 3b+ in four server racks, configured in a big square box reminiscent of a British Police box, popularized in a certain British Television TV series. Fast forward to today, the Pi Cluster, “The Raspberry Pi Super Computer (Pi Cluster),” got sent to e-waste, some parts stripped off it, was dormant for 2 years, and then in May of this year found it’s way to my garage where it got a complete overhaul.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4veoQ9l84Oop2dOwStP4Yg.jpeg" /><figcaption>The Raspberry Pi Super Computer at Open World San Francisco 2019</figcaption></figure><h3>A Temporal History</h3><h4>2018</h4><p>In early 2018, a small group of enthusiastic pre-sales engineers from Oracle Switzerland presented their 12-node Raspberry Pi cluster at the Hackzurich hackathon, mimicking an Oracle Cloud data center with 3 availability domains. It ran a fully-operational Kubernetes cluster and could demo node and availability domain fail-overs. Gerald Venzl wrote about this in <a href="https://blogs.oracle.com/developers/post/building-the-worlds-largest-raspberry-pi-cluster">Building the world’s largest Raspberry Pi cluster</a>. Fast forward to Open World 2018 in October: Stephen Chin and Gerald Venzl presented me with this cluster and the concept of doing a LOT of small ones that could come together and become a really big one. Gerald thought 1,000 Pi would be cool. I told him “That is a terrible number. You need 1024”. Gerald and Stephen got big smiles on their faces and the seed of the Pi Cluster was planted. Over the coming months Jasper Potts and I brainstormed how to make this happen and started making spreadsheets of parts, and I reached out to our suppliers to get quotes for all of them.</p><h4>2019</h4><p>The idea spread around the company and garnered support from the leads of all the teams from which we would showcase technology. Approvals for purchases started happen. I went shopping for a lab because we were going to need a lot of space. We needed a lab for the other experiences we built like Bullet Time or the Escape Rooms, so it was a necessity. I kitted it out with soldering irons, oscilloscope, 3D printers, 4 legged desks, and everything else you could need for a real Maker’s space. We considered using the Pi Compute modules — and there were some really cool 4-Pi boards — but 250 of them would be too expensive. We thought about custom boards, but that would take too much time. That’s when we decided to use off-the-shelf hardware that anyone can buy, and just use a regular Raspberry Pi 3B+. The Pi 4 wasn’t available yet. The Pi arrived February 2019 before I had my lab, and got stored in other labs until June when the Developer Marketing Hacker Lab was finally opened.</p><p>Between February and April I did a lot of traveling to support the existing experiences, ordering parts. and brainstorming and research on how to build this cluster. Jasper Potts and I would talk almost daily, trying to make sure we had every possibly part we needed, to make sure each piece of the project was going to be possible, and contingency plans in case things didn’t work out. The four problems at this point were:</p><p>1. Power<br>2. Networking<br>3. SD Cards<br>4. Software<br>5. What would it look like</p><p>I eventually found a 60-port USB power supply, ordered one to test. It worked, so I ordered 30 of them. It’s always good to have backups. After some initial network tests with an 8 Pi Cluster with standard home routers and gateways, we realized a standard home network wasn’t going to work. If we built a lot of tiny Pi Clusters there were the problems of cost for all the routers and gateways, then when the cluster came together as one, each cluster would a “cluster of clusters” a couple times in a tree configuration, where each node is either a single Pi or a a tiny cluster. It would have to be a cluster of clusters, or be “reconfigurable”. Any way you do it, configuring and maintaining this would be a lot of work. But with over 255 devices to be a single cluster we had to go with Class B, and that’s when serious networking equipment is needed.</p><p>In May Stephen Chin and I sat down with a list of problems. We had power solved, at least for the Pi. We would have to readdress this for the entire cluster. We went with Ubiquity networking. It‘s the least expensive of the serious networking hardware, and has all the features that we would need. We decided to not order SD cards and try for network booting. This would come back to bite us later, but SD cards for every Pi would take too much time and cost $16,000. Network booting would solve a lot of problems, but I’ll dig into this later. Writing software for anything like this is challenging and people get their doctorates and spend entire careers coming up with algorithms that can be split across multiple threads or compute modules. We decided to bring in Johan Vos and José Pereda of GLUON and do this as a Java community project. They brought in Gerrit Grunwald and a few other people I wasn’t even aware were doing work.</p><p>The last piece of the puzzle was what would it look like. I had started prototyping and researching different ways to hold the Pi, but it started to look like this thing would be about 8–12 server racks if I went with the typical density I was seeing on the internet. I sat down with a dozen Pi, a couple Ubiquity switches, and mounted them in a small server rack. I then held the Pi next to one another in different configurations. In a 1U, they’d have to all lay flat — I could only get 4 to fit. But if I put them in vertically, it would be a 2U but a lot more could be stacked.</p><p>Over coffee — then lunch — at the dining room table, we discussed putting it into an old VAX or Cray CS6400 with seats. A big rainbow arch that people can walk under. We even thought about a tree where the Pi grew on it like fruit. I showed him some of the prototype work. We realized that for logistics it needed to be a box. We did the math and thought we could cram it all into 4 racks. Maybe. It was going to be tight. But if we could, then a telephone booth would be cool. Superman had a cool telephone booth. Maybe a red British one. Or…a blue British Police Box. We both got a bit smile went to work with some renderings, slide decks, and more prototyping. But Jasper Potts rendering is the one that we started using.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*empw76lhwx3kna7rk-WUwg.png" /><figcaption>First Rendering of Pi Cluster</figcaption></figure><p>I was trying to get the highest density I could by cramming at least 20 Pi into a 2U. The problem was that this left us with about 50 extra Pi, so it wouldn’t fit. It’s kind of like the rocket equation: the more Pi you have, the more infrastructure you need, thus the more space and power. At first I 3D-printed a huge print where the Pi just slid into place and were held in with another print. Unfortunately, my printer wouldn’t print a full rack that size, and if it could, it took 24 hours. I tried a lot of things. That’s when I got the idea to use an 18&quot; 1&quot;x1/2&quot; piece of 80/20 with the end milled off by 16.35mm, then tap the hols in the ends, print 21 Pi caddies and two ends, and that was the solution. I should back up at this point and mention that we <em>did</em> consider POE for all the Pi. We tried this, but the POE hat was mutually exclusive because it required some firmware changes to network booting, then all the switches would have to have all POE ports. I had difficulty finding more than 16-port POE switches and the density would have been half of what we were able to get.</p><p>Everything was moved to the Developer Marketing Hacker Lab in June and a few people, like Blaine Carter, flew out to help set it up. I decided to bring in my camera and tripod and record what was going on, giving the camera little attention besides making sure it was pointed in the general direction. This video would later become Pi Cluster Video on March 14th 2020. World’s Largest Raspberry Pi Cluster (that we know of):</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FKbVcRQQ9PNw%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DKbVcRQQ9PNw&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FKbVcRQQ9PNw%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/4db7dd0b0bc4e35440bf3aea8220a5f1/href">https://medium.com/media/4db7dd0b0bc4e35440bf3aea8220a5f1/href</a></iframe><p>I did record a few choice moments. At this point in time I had discovered Casey Neistat and thought his videos were interesting.</p><p>I was trying to document everything as I went, knowing full well it’s nearly impossible to document after the fact. Here are the blogs from that time describing the caddies and how they came to be.</p><ul><li><a href="http://chrisbensen.blogspot.com/2019/06/very-large-raspberry-pi-cluster-part-i.html">Very Large Raspberry Pi Cluster Part 1</a></li><li><a href="http://chrisbensen.blogspot.com/2019/06/very-large-raspberry-pi-cluster-part-ii.html">Very Large Raspberry Pi Cluster Part 2</a></li><li><a href="http://chrisbensen.blogspot.com/2019/06/very-large-raspberry-pi-cluster-part-iii.html">Very Large Raspberry Pi Cluster Part 3</a></li><li><a href="http://chrisbensen.blogspot.com/2019/07/very-large-raspberry-pi-cluster-part-iv.html">Very Large Raspberry Pi Cluster Part 4</a></li><li><a href="http://chrisbensen.blogspot.com/2019/07/very-large-raspberry-pi-cluster-part-v.html">Very Large Raspberry Pi Cluster Part 5</a></li><li><a href="http://chrisbensen.blogspot.com/2019/07/very-large-raspberry-pi-cluster-part-vi.html">Very Large Raspberry Pi Cluster Part 6</a></li><li><a href="https://www.thingiverse.com/thing:3958586">3D Printed Parts</a></li></ul><p>During this project, I started actually posting to Twitter. I took this video while heading home at midnight, edited the video with iMovie on my phone while waiting for the elevator doors to open, and while walking to my car. By the time I got to my car, I had posted it.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FROC2FhExiRY%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DROC2FhExiRY&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FROC2FhExiRY%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/cd1208838fbffb50a84edec7b5dd250b/href">https://medium.com/media/cd1208838fbffb50a84edec7b5dd250b/href</a></iframe><p>I was actively recruiting. We still had a lot of unknowns, but one of the big ones was the time it would take. If something takes 1 minute and you have 1,000 of them, then that’s over 16 hours. Blaine Carter and I were busy printing 1,000 caddies, the end brackets, and everything else that we needed that was custom from a total of — get this —<em> twelve</em> 3D printers. The brackets took 45 minutes —<em> after</em> optimizations. There were months of 3D printing, but we had to be sure they were perfect. 3D printing is amazing and can print a thing out of nowhere in a short period of time, but if you need 1,000 of them, it’s going to take a long time. Yolande Poirier knew of some students at 42 Silicon Valley who came by and started helping. I bought them pizza offered to mentor them. They came back the next day with friends. Some students would change, but a core group who I remain friends with today came day after day. We set up assembly lines for removing the Pi from their packaging, lining them up for install into caddies, and assembling them into a 2U rack of 21 Pi. We ended up with 50 2U caddies. Actually, the plan was to build two 84 Pi Mini Clusters so we made 9 more for a total of 59. One was extra, but it turned out we needed this one. I’ll explain later.</p><p>Slowly the Pi Cluster took shape. The printers were running 24–7. I started working 7 days a week, and at least 15 hours a day. It wasn’t healthy, but everyone working on it was having a great time. Great people. I made sure we always had food and cool toys — that’s all an engineer needs besides a little bit of sleep. The students were learning a lot, and they were smart, so things got done.</p><p>One of the parallel tasks was the software, and for any software project you need a good operating system. The idea had been presented to Wim Coekaerts and the Oracle Linux team, and they were 100% on board to give the Pi Cluster a custom version of Oracle Linux 7. A good friend of mine, Roy Feague, had some time on his hands and was enjoying the challenge of network booting the Pi. The Pi is designed to network boot, but we found that the firmware had a bug. When the Pi boots up to communicate with the DHCP server to get an IP address, it doesn’t do a correct lease, release, and bind. It renews the IP but stops there. So multiple Pi get the same IP. So we had to get the MAC address of every single Pi and hard code it into the dhcpd.conf. It seems backwards to use DHCP only to have static IP addresses, but there you have it. Roy started off with Ubuntu and Raspbian so we could use an NFS mount shared by all the Pi and use an overlay file system so none of them did a write-back. Here’s a good article on <a href="https://linuxhit.com/raspberry-pi-pxe-boot-netbooting-a-pi-4-without-an-sd-card/">Raspberry Pi PXE Boot — Network booting a Pi 4 without an SD card</a> that didn’t exist back then. The net boot process works like this:</p><ol><li>Power on the Pi, NIC firmware sends DHCP request</li><li>DHCP server responds with a lease and server options</li><li>Pi configures network and requests bootstrap files</li><li>Server sends files to client via TFTP</li><li>Pi boots kernel and boostrap image then complets OS boot.</li></ol><p>The Oracle Linux team got Oracle Linux 7 working with a small 8-Pi cluster, and we had the rest of the cluster coming together, so we tested booting, but we had to boot 42 Pi at a time. This is where Ubuntu fell over. Oracle Linux 7 was tuned and worked great. Not perfect — even to this day with Oracle Linux 9 it doesn’t work perfectly. We think it’s because of network hiccups or Pi firmware glitches. Most of the time, when we boot 42 Pi they all boot. But once in a while only 37 will boot, and occasionally less than that. The process is to shut down and try again.</p><p>At this point, it’s early October 2019 the Pi cluster is nearly all assembled, the operating system is mostly working, we can boot most of the Pi, and it’s time to ship the cluster to Moscone for Open World San Francisco 2019. The design of the cluster was to bolt plywood to it and it would become the crate. The casters installed on it weren’t good for rolling, so we used a pallet jack. We actually had to remove a railing from the freight elevator to get it in, but we got it on the truck with a GoPro mounted in place so we could get transportation video. Turned out the battery died — I didn’t set it to time-lapse. I’m not a big fan of single button interfaces.</p><p>Once at Open World we set it up, installed the Java community project and managed to boot 980 Pi. The day after the Pi Cluster debuted, 42 news outlets, including <a href="https://www.tomshardware.com/news/oracle-raspberry-pi-supercomputer,40412.html">Tom’s Hardware</a> and <a href="https://developers.slashdot.org/story/19/09/21/0334244/oracles-new-supercomputer-has-1060-raspberry-pis">Slashdot</a> were reporting on the cluster. There were a few random Pi that wouldn’t boot, and a bank of 42 that I couldn’t reach which had become unplugged. But the heat was too high to leave it on for any extended period. We had 7 large fans, and had some experts come look to give us their opinion on cooling, but the common response was “well, it might work…”. The top half did. The bottom half, especially those under the server that went clear across, blocked the flow of air and those Pi overheated.</p><p>After Open World the Pi Cluster went back to the Developer Marketing Hacker Lab for upgrades and repairs and a trip around the world. It was going to London, Milan, Berlin, and New York City. But after talking with the events teams at each of these locations, the earlier requirements — 200amps of power and double doors — were difficult to satisfy. We went around and around. Finally, I decided to build one of the 84 Pi Mini Clusters I had plans for, and on December 20th 2019, it shipped out for Open World Dubai in January of 2020.</p><p>Here is a <a href="http://chrisbensen.blogspot.com/2020/11/parts-list-for-raspberry-pi-mini-super.html">parts list for the 84 Raspberry Pi Mini Cluster</a>.</p><h4>2020</h4><p>I met up with the cluster at Open World London in February 2020 and instead of a Java community project, I ran SETI@home.</p><p>This was the beginning of the pandemic, and all future events were canceled and lots of internal shuffling ensued. One big shuffle was that everything was going virtual. I realized I had a lot of video footage of building the Pi Cluster, and Pi Day was coming up, so I spent a few days editing a video trying to tell a fun story. The result was this viral video, thanks in big part to Jim Grisanzio.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FKbVcRQQ9PNw%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DKbVcRQQ9PNw&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FKbVcRQQ9PNw%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/4db7dd0b0bc4e35440bf3aea8220a5f1/href">https://medium.com/media/4db7dd0b0bc4e35440bf3aea8220a5f1/href</a></iframe><p>At this point, I proposed a few other virtual experiences. The most notable was the <a href="https://github.com/chrisbensen/eff-uno-racer">LEGO© Inspired Race Car</a>, which started the partnership between Oracle and Red Bull.</p><p>As part of the internal shuffling, there was the closing of the Developer Marketing Hacker Lab. We transferred tools and items to other labs and other storage options where possible. I transferred my lab to Oracle Labs as one of their labs, and left the Pi Cluster there with signs to save: Do Not Trash. We had the Santa Cruz fires the same week the lab was being cleared out, and I got a call that the Pi Cluster was in e-waste. When the lab was cleaned out, they cleared it out — everything that wasn’t nailed down. I drove into the office and pushed the Pi Cluster back into the lab, but a couple switches, two Pi 2U racks, and a 60-port USB power supply had been removed. There wasn’t much I could do about it — or some of the other stuff that got tossed into e-waste that had “save” written on it. After all, I was living out of a suitcase for a couple weeks after the fire evacuation. But the Pi Cluster sat like that for another year and a half. Fortunately it had two smaller 84 Pi Mini Clusters for company. In November of 2020 I recorded a video building the 2nd 84 Pi Mini Cluster in my garage and posted it to YouTube.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FQZ9LufeXdgw%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DQZ9LufeXdgw&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FQZ9LufeXdgw%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/6bd001776b0d8487c178cf3646d85db3/href">https://medium.com/media/6bd001776b0d8487c178cf3646d85db3/href</a></iframe><h4>2022</h4><p>The Pi Cluster had come up a few times in conversation but due to its unknown status and no physical conferences, it collected dust. Finally, in February of 2022, the conversations got serious. This is when the Pi Cluster came to visit me and my family at home, where it’s stayed for the past 6 months.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FELvkg_88XSY%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DELvkg_88XSY&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FELvkg_88XSY%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/1f5ed98da75efb53f5029f6da2f514a9/href">https://medium.com/media/1f5ed98da75efb53f5029f6da2f514a9/href</a></iframe><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FKoWfrwZuJ78%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DKoWfrwZuJ78&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FKoWfrwZuJ78%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/c32a30bd9353c5526c6a621adaecce3f/href">https://medium.com/media/c32a30bd9353c5526c6a621adaecce3f/href</a></iframe><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FMpb9L9NwBZw%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DMpb9L9NwBZw&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FMpb9L9NwBZw%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/64091bcda9a0bbd26938e59176918954/href">https://medium.com/media/64091bcda9a0bbd26938e59176918954/href</a></iframe><p>If you are interested in other posts, I created a blog post to include all Pi Cluster-related posts <a href="http://chrisbensen.blogspot.com/2020/11/all-raspberry-pi-super-computer-posts.html">here</a>. It has since gotten out of date but it includes everything up through 2020.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4e4b1e214bdd" width="1" height="1" alt=""><hr><p><a href="https://medium.com/oracledevs/a-temporal-history-of-the-worlds-largest-raspberry-pi-cluster-that-we-know-of-4e4b1e214bdd">A Temporal History of The World’s Largest Raspberry Pi Cluster (that we know of)</a> was originally published in <a href="https://medium.com/oracledevs">Oracle Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Create a Simple Docker Container with a Python Web Server]]></title>
            <link>https://medium.com/oracledevs/create-a-simple-docker-container-with-a-python-web-server-26534205061a?source=rss-279db4a5cf86------2</link>
            <guid isPermaLink="false">https://medium.com/p/26534205061a</guid>
            <category><![CDATA[docker]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[web-server]]></category>
            <category><![CDATA[oracle]]></category>
            <dc:creator><![CDATA[Chris Bensen]]></dc:creator>
            <pubDate>Wed, 03 Aug 2022 18:32:01 GMT</pubDate>
            <atom:updated>2023-03-08T23:39:03.256Z</atom:updated>
            <content:encoded><![CDATA[<p>By <a href="https://twitter.com/chrisbensen">Chris Bensen</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Dy7HggA1e1SFBZCq5x0QNg.jpeg" /><figcaption><a href="https://www.pexels.com/photo/cargo-containers-trailer-lot-1624695/">Photo by Frans van Heerden</a></figcaption></figure><p>If you prefer you can read this blog post on GitHub <a href="https://github.com/chrisbensen/chris-blogs/blob/main/HowTo/DockerWebServer/DockerWebServer.md">here</a>.</p><p>This article may seem obvious to some, but others need to know how to get started. Having a server running in a container is the beginning of so many great things.</p><h4>Prerequisites</h4><ol><li>Install <a href="https://www.docker.com/">Docker</a>.</li><li>Read <a href="https://medium.com/oracledevs/create-a-simple-python-web-server-on-oci-1d3634a1d7c2">Create a Simple Python Web Server</a> because we will use this Web Server but put it into a Docker container.</li></ol><h4>Build a Web Server</h4><ol><li>Create a folder and put all the files we are going to create into that folder.</li><li>Create <a href="https://github.com/chrisbensen/chris-blogs/blob/main/HowTo/DockerWebServer/files/index.html">index.html</a>:<br> <br> &lt;!DOCTYPE html&gt;<br> &lt;html&gt;<br> &lt;body&gt;<br> Hello World<br> &lt;/body&gt;<br> &lt;/html&gt;</li><li>Create <a href="https://github.com/chrisbensen/chris-blogs/blob/main/HowTo/DockerWebServer/files/server.py">server.py</a>:</li></ol><pre><br> <br> #!/usr/bin/python3<br> from http.server import BaseHTTPRequestHandler, HTTPServer<br> import time<br> import json<br> from socketserver import ThreadingMixIn<br> import threading</pre><pre>hostName = “0.0.0.0”<br> serverPort = 80</pre><pre>class Handler(BaseHTTPRequestHandler):<br> def do_GET(self):<br> # curl http://&lt;ServerIP&gt;/index.html<br> if self.path == “/”:<br> # Respond with the file contents.<br> self.send_response(200)<br> self.send_header(“Content-type”, “text/html”)<br> self.end_headers()<br> content = open(‘index.html’, ‘rb’).read()<br> self.wfile.write(content)</pre><pre>else:<br> self.send_response(404)</pre><pre>return</pre><pre>class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):<br> “””Handle requests in a separate thread.”””</pre><pre>if __name__ == “__main__”:<br> webServer = ThreadedHTTPServer((hostName, serverPort), Handler)<br> print(“Server started http://%s:%s&quot; % (hostName, serverPort))</pre><pre>try:<br> webServer.serve_forever()<br> except KeyboardInterrupt:<br> pass</pre><pre>webServer.server_close()<br> print(“Server stopped.”)<br> ```</pre><h4>Put Everything into a Docker Container</h4><ol><li>Create <a href="https://github.com/chrisbensen/chris-blogs/blob/main/HowTo/DockerWebServer/files/Dockerfile">Dockerfile</a>:<br><br> FROM python:3<br> ADD index.html index.html<br> ADD server.py server.py<br> EXPOSE 8000<br> ENTRYPOINT [“python3”, “server.py”]</li><li>cd into the folder you created.</li><li>Run docker build -f Dockerfile . -t web-server-test</li><li>Run docker run -rm -p 8000:80 — name web-server-test web-server-test</li></ol><p>There you have it! Enjoy your web server in a Docker container. The nice thing about doing this is as a developer you can run and debug things inside a container just as if they are on your local computer but the only thing that is installed on your local system is Docker.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=26534205061a" width="1" height="1" alt=""><hr><p><a href="https://medium.com/oracledevs/create-a-simple-docker-container-with-a-python-web-server-26534205061a">Create a Simple Docker Container with a Python Web Server</a> was originally published in <a href="https://medium.com/oracledevs">Oracle Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Poor Man’s Auto Update]]></title>
            <link>https://medium.com/oracledevs/poor-mans-auto-update-eb5bfdfe39cf?source=rss-279db4a5cf86------2</link>
            <guid isPermaLink="false">https://medium.com/p/eb5bfdfe39cf</guid>
            <category><![CDATA[oci]]></category>
            <category><![CDATA[auto-update]]></category>
            <category><![CDATA[oracle-cloud]]></category>
            <category><![CDATA[raspberry-pi]]></category>
            <dc:creator><![CDATA[Chris Bensen]]></dc:creator>
            <pubDate>Tue, 28 Jun 2022 23:31:37 GMT</pubDate>
            <atom:updated>2022-11-07T16:11:36.649Z</atom:updated>
            <content:encoded><![CDATA[<p>by <a href="https://twitter.com/chrisbensen">Chris Bensen</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eeLt9i2ipA4wIR-EAZ0pBQ.jpeg" /><figcaption>Photo by Miguel Á. Padriñán: <a href="https://www.pexels.com/photo/close-up-shot-of-keys-on-a-red-surface-2882668/">https://www.pexels.com/photo/close-up-shot-of-keys-on-a-red-surface-2882668/</a></figcaption></figure><p>Back in the good old days GitHub allowed anonymous downloads. Now it requires username/password or ssh key. That’s no good when the Pi is out of your control. Thus, introducing the Chris Bensen Poor Man’s Auto Update. Whatever you do, do not do this at home, I am a professional and understand the security vulnerabilities.</p><p>The scenario is this: you have a script that runs on your Raspberry Pi and you need to update it. Let’s assume your script is setup to run on boot as a chron job. You can read about setting up a chron job on a Raspberry Pi <a href="https://bc-robotics.com/tutorials/setting-cron-job-raspberry-pi/">here</a>.</p><h3>Steps</h3><ol><li>Create the local directory structure on the Pi where ‘file.py’ is your script.</li></ol><pre>/updater<br>├── repo<br>│ ├── file.py<br>├── file.py<br>├── updater.py<br></pre><p>2. Copy this bash script.</p><p><a href="https://github.com/chrisbensen/chris-blogs/blob/main/WeekendHacks/PoorManAutoUpdate/files/updater.sh">updater.sh</a></p><pre>#!/bin/bash</pre><pre>curl -X GET \<br>  &lt;UrlToFile&gt; \<br>  -o file.py</pre><pre>file1=”/users/pi/updater/repo/file.py”<br>file2=”/users/pi/updater/file.py”</pre><pre>if cmp -s “$file1” “$file2”; then<br>  # same, do nothing<br>  echo “same”<br>else<br>  # different<br>  echo “different”<br>  cp $file1 $file2</pre><pre>  reboot<br>fi</pre><p>3. Create a Oracle Cloud Object Store bucket.<br>4. Make that bucket public.<br>5. Copy your file to the bucket.<br>6. Edit the script by changing the &lt;UrlToFile&gt;. Get the URL from the Object Details and remove the file name from the end so you just have the following parts of the URL: {accountRestEndpointURL}/{containerName}/{objectName}<br>7. Edit the script so the paths are correct.<br>8. Setup a chron job to run `updater.py` as often as you want to check for updates. Every 5 minutes might be overkill but let’s start with that. You can read about setting up a chron job on a Raspberry Pi <a href="https://bc-robotics.com/tutorials/setting-cron-job-raspberry-pi/">here</a>.</p><p>You can read the documentation about the downloading a file from Object Store <a href="https://docs.oracle.com/en/cloud/cloud-at-customer/occ-get-started/download-file.html">here</a>.</p><h3>Overview</h3><p>The file updater/repo/file.py is the one that gets copied down. The script then compares it to the one in the updater directory. If they are different the updater directory is updated with the new one. updater/file.py is the one you want a symlink pointed to.</p><p>The <strong>reboot</strong> in updater.py will reboot the Pi which starts the updated file.py script. I know this is not the absolute best way to do this but it works and is fairly foolproof.</p><p>So there you have it, a poor man’s auto update.</p><h3>Conclusion</h3><p>Now I do know with OCI Object Store you can use an API for a pre-authenticated request. If you use a REST call from the Pi, you can keep the Object Store Private. However, that is additional work and I’m going to leave that for an excersise for the user, or a future post!</p><p>Meanwhile, you can chat about this <a href="https://bit.ly/devrel_slack">on our public Slack</a>, or <a href="https://signup.cloud.oracle.com/?language=en&amp;sourceType=:ex:tb:::::&amp;SC=:ex:tb:::::&amp;pcode=">sign up for Free Tier</a> and try it yourself.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=eb5bfdfe39cf" width="1" height="1" alt=""><hr><p><a href="https://medium.com/oracledevs/poor-mans-auto-update-eb5bfdfe39cf">Poor Man’s Auto Update</a> was originally published in <a href="https://medium.com/oracledevs">Oracle Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introducing Pyrsia]]></title>
            <link>https://medium.com/oracledevs/introducing-pyrsia-5408c7c3d527?source=rss-279db4a5cf86------2</link>
            <guid isPermaLink="false">https://medium.com/p/5408c7c3d527</guid>
            <category><![CDATA[jfrog]]></category>
            <category><![CDATA[pyrsia]]></category>
            <category><![CDATA[oracle]]></category>
            <category><![CDATA[open-source]]></category>
            <dc:creator><![CDATA[Chris Bensen]]></dc:creator>
            <pubDate>Wed, 01 Jun 2022 19:49:44 GMT</pubDate>
            <atom:updated>2022-11-07T16:11:56.386Z</atom:updated>
            <content:encoded><![CDATA[<p>by <a href="https://twitter.com/chrisbensen">Chris Bensen</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/377/1*QkmmKQpSM4T5tR2lHpEXNA.png" /><figcaption>Pyrsia</figcaption></figure><p>If you prefer you can read this blog post on GitHub <a href="https://github.com/chrisbensen/chris-blogs/blob/main/posts/PyrsiaIntroduction/PyrsiaIntroduction.md">here</a>.</p><p>From the experts of binary management, <a href="https://www.jfrog.com/">JFrog</a>, comes <a href="https://pyrsia.io/">Pyrsia</a>. <a href="https://pyrsia.io/">Pyrsia</a> is a solution to the open source software supply chain like nothing you’ve seen before. You can read a little about it <a href="https://github.com/pyrsia">here</a>, <a href="https://jfrog.com/blog/pyrsia-open-source-software-that-helps-protect-the-open-source-supply-chain/">here</a> and <a href="https://www.businesswire.com/news/home/20220525005671/en/JFrog-Ushers-in-New-Era-of-Open-Source-Software-Security-Launching-Project-Pyrsia-to-Help-Prevent-Software-Supply-Chain-Attacks">here</a>.</p><p>My high level synopsis is: It’s crazy we install open source software from builds that are not verified. Sure it’s convenient, but you might as well leave your front door open.</p><p><a href="https://pyrsia.io/">Pyrsia</a> is a work in progress, but it solves all of this. Trusted entities run a Pyrsia node that builds the source and everything lives in a blockchain. This is not a blockchain to make wealth or one that will use up power plants to mine coins, this is a blockchain with a purpose. The source-to-binary transition (software supply chain) hashes are all verified and authenticated so when you download something you know a binary was built from a specific source. Take this a step further, and any security audit done will be given back to the community — so big or small companies will benefit and the entire sofware supply chain is much better off.</p><p>This is a war to protect all CPU cycles against bad actors. I guarantee we are all running trojan horses in packages or libraries we’ve installed via some package manager at one point or another. It’s impossible to protect against. <a href="https://pyrsia.io/">Pyrsia</a> solves this. This is why Oracle is getting involved.</p><p>If you have any questions or for interactive support and community check out Oracle’s public <a href="https://bit.ly/devrel_slack">Slack channel</a> for developers.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5408c7c3d527" width="1" height="1" alt=""><hr><p><a href="https://medium.com/oracledevs/introducing-pyrsia-5408c7c3d527">Introducing Pyrsia</a> was originally published in <a href="https://medium.com/oracledevs">Oracle Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Project Kessel Run]]></title>
            <link>https://medium.com/oracledevs/project-kessel-run-fc081eb0fd03?source=rss-279db4a5cf86------2</link>
            <guid isPermaLink="false">https://medium.com/p/fc081eb0fd03</guid>
            <category><![CDATA[cloud]]></category>
            <category><![CDATA[oracle]]></category>
            <category><![CDATA[arduino]]></category>
            <category><![CDATA[rockets]]></category>
            <category><![CDATA[pi]]></category>
            <dc:creator><![CDATA[Chris Bensen]]></dc:creator>
            <pubDate>Wed, 04 May 2022 21:50:03 GMT</pubDate>
            <atom:updated>2022-11-07T16:12:23.388Z</atom:updated>
            <content:encoded><![CDATA[<p>By <a href="https://twitter.com/chrisbensen">Chris Bensen</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1V6wTrotKXafpnjkmeb4SQ.png" /></figure><p>If you prefer you can read this blog post on GitHub <a href="https://github.com/chrisbensen/chris-blogs/blob/main/WeekendHacks/rocket/rocket.md">here</a>.</p><p>Rockets are cool, so why not create a cloud connected rocket? I’m calling this one Kessel Run. Happy May the 4th be with you! This is an IoT rocket.</p><p>The flight computer is an Arduino + LoRa trasceiver + GPS + Acceleromiter broadcasting to a base station running a Raspberry Pi + LoRa transceiver connected to my cell phone’s hotspot to the internet, and sending everything to the Oracle Cloud.</p><h3>Prerequisites</h3><p>To build one you will need a few things.</p><p>1. You have an OCI account or a <a href="https://medium.com/oracledevs/create-an-oracle-always-free-cloud-account-bc6aa82c1397">Free Tier Account</a>.</p><p>1. Get the parts from <a href="https://demoparts.withoracle.cloud/sharedbom?ref=295451616379598227377985226295520958226">here</a>.</p><p>2. Download the 3D printable files from <a href="https://www.thingiverse.com/thing:5377245">Thingiverse</a>.</p><h4>Building the Rocket</h4><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F0xlxQlmg2g8%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D0xlxQlmg2g8&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F0xlxQlmg2g8%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/19b100bc4346d4d9113aa1ec4c419837/href">https://medium.com/media/19b100bc4346d4d9113aa1ec4c419837/href</a></iframe><p>Assembly is fairly stright forward. Download the 3D printable files and the fins. If you have access to a laser cutter it’s super simple, otherwise print out the <a href="https://github.com/chrisbensen/chris-blogs/blob/main/WeekendHacks/rocket/files/models/rocketfins.pdf">rocketfins.pdf</a>, place it over some thing balsawood and use a craft knife to cut out three wings as stabilizers.</p><p>The nose cone comes in two pieces. To print those, I used a .4mm nozzle. If you add electronics you can also print out the battery holder, or if you use a different battery you’ll want to customize it. An easy hack is to attach the wires to the ends of the battery using electrical tape.</p><h4>Flight Computer</h4><p>For this step you’ll need the following items from the prerequisites above:</p><ul><li><a href="https://learn.adafruit.com/adafruit-rfm69hcw-and-rfm96-rfm95-rfm98-lora-packet-padio-breakouts">Lora Transeiver</a></li><li><a href="https://www.etechnophiles.com/arduino-micro-pinout-schematic-and-specifications/">Arduino Micro</a></li><li><a href="https://www.adafruit.com/product/746">GPS</a></li><li><a href="https://www.sparkfun.com/products/17241">Accelerometer</a></li></ul><h4>Wiring of the Flight Computer</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IX3nXJehZrxiLrddDef-5w.jpeg" /></figure><p>Arduino Micro -&gt; LoRa<br>MISO-pin 50 -&gt;LoRa MISO<br>MOSI-pin 51 -&gt;LoRa MOSI<br>SCK- Pin 52 -&gt;LoRa SCK<br>Pin 9 -&gt;LoRa CS<br>Pin 8 -&gt;LoRa RST<br>Pin 7 -&gt;LoRa G0<br>3.3v -&gt;LoRa 3.3v<br>GND -&gt;Lora GND</p><p>Arduino Micro -&gt; GPS<br>Pin 3 -&gt; ADXL313 SCL<br>Pin 2 -&gt; ADXL313 SDA<br>3.3v -&gt;ADXL313 3.3v<br>GND -&gt;ADXL313 GND</p><p>Arduino Micro -&gt; GPS<br>Pin 6 -&gt; GPS TX<br>Pin 5 -&gt; GPS RX<br>3.3v -&gt;GPS 3.3v<br>GND -&gt;GPS GND</p><p>I used the 433 MHz LoRa transeiver and it needs an antenna. For the 433 MHz band the wavelength is 299.792.458 / 433.000.000 = 69,24 cm. A quarter is 17,31 cm which is a good length so I cut a wire that length and soldered it to the antenna of both the trasmitter and receiver.</p><h4>Prototype Breadboard of Flight Computer</h4><p>The flight computer needed to be shrunk down, so I soldered on some headers and wired up a prototype breadboard.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fZKH0s-FGBIPVSpe7JALrQ.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*j7UzM6FqtRE76jzX93R2Cg.jpeg" /></figure><h4>Base Station</h4><p>The base station is a Raspbery Pi connected to a LoRa transeiver which is connected to a phone via the phones mobile hotspot. The transceiver must be the same as the one installed in the flight computer.</p><p><a href="https://learn.adafruit.com/adafruit-rfm69hcw-and-rfm96-rfm95-rfm98-lora-packet-padio-breakouts">Lora Transceiver</a><br>Any Pi 3 or Pi 4 will work.</p><p>Pi -&gt; LoRa<br>Pi Pin MOSI -&gt; LoRa MOSI<br>Pi Pin MISO -&gt; LoRa MISO<br>Pi Pin SCK -&gt; LoRa SCK<br>Pi Pin 25 -&gt; LoRa CS<br>Pi Pin 5 -&gt; LoRa RST<br>Pi Pin CE1 -&gt; LoRa G0<br>Pi Pin 3.3v -&gt; LoRa VIN<br>Pi Pin GND -&gt; LoRa GND</p><h3>May The Source Be With You</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/441/1*qMCyTaBAAK-GOwWyyshQ3g.png" /></figure><p>Upload the following sketch to the Arduino. Note that you will also need the files <a href="https://github.com/chrisbensen/chris-blogs/blob/main/WeekendHacks/rocket/files/cloudrocket/LoRa.h">lora.h</a> and <a href="https://github.com/chrisbensen/chris-blogs/blob/main/WeekendHacks/rocket/files/cloudrocket/LoRa.cpp">lora.cpp</a>.</p><pre><a href="https://github.com/chrisbensen/chris-blogs/blob/main/WeekendHacks/rocket/files/cloudrocket/cloudrocket.ino">cloudrocket.ino</a><br><br>//Board: Arduino Mega 2560<br>//Processor: ATMega 2560</pre><pre>// LoRa<br>// <a href="https://www.adafruit.com/product/3073">https://www.adafruit.com/product/3073</a><br>// ATMega2650 -&gt;LoRa<br>// MISO-pin 50 -&gt;LoRa MISO<br>// MOSI-pin 51 -&gt;LoRa MOSI<br>// SCK- Pin 52 -&gt;LoRa SCK<br>// Pin 7 -&gt;LoRa CS<br>// Pin 6 -&gt;LoRa RST<br>// Pin 2 -&gt;LoRa G0<br>// SS- pin 53 //N/A<br>//<br>// Arduino Micro -&gt;LoRa<br>// MISO-pin 50 -&gt;LoRa MISO<br>// MOSI-pin 51 -&gt;LoRa MOSI<br>// SCK- Pin 52 -&gt;LoRa SCK<br>// Pin 9 -&gt;LoRa CS<br>// Pin 8 -&gt;LoRa RST<br>// Pin 7 -&gt;LoRa G0<br>// 3.3v -&gt;LoRa 3.3v<br>// GND -&gt;Lora GND<br>#include &lt;SPI.h&gt;<br>#include “LoRa.h”</pre><pre>const int csPin = 9; // LoRa radio chip select<br>const int resetPin = 8; // LoRa radio reset<br>const int irqPin = 7; // interrupt request pin</pre><pre>const byte localAddress = 0xBB;<br>const byte destinationAddress = 0xFF;<br>const byte syncWord = 0xB4; // Sync word (network ID)<br>const byte spreadingFactor = 7; //spreading factor (6–12)</pre><pre>// Accelerometer<br>// <a href="https://learn.sparkfun.com/tutorials/sparkfun-qwiic-3-axis-accelerometer-adxl313-hookup-guide?_ga=2.60797357.1096858093.1651183108-2026033215.1651006494">https://learn.sparkfun.com/tutorials/sparkfun-qwiic-3-axis-accelerometer-adxl313-hookup-guide?_ga=2.60797357.1096858093.1651183108-2026033215.1651006494</a><br>// Arduino Micro -&gt; Accelerometer<br>// Pin 3 -&gt; ADXL313 SCL<br>// Pin 2 -&gt; ADXL313 SDA<br>// 3.3v -&gt;ADXL313 3.3v<br>// GND -&gt;ADXL313 GND<br>#include &lt;Wire.h&gt;<br>#include &lt;SparkFunADXL313.h&gt;<br>ADXL313 myAdxl;<br>const int accelerometerIC2Address = 0x1D;</pre><pre>// GPS<br>// <a href="https://www.adafruit.com/product/746">https://www.adafruit.com/product/746</a><br>// Arduino Micro -&gt; GPS<br>// Pin 6 -&gt; GPS TX<br>// Pin 5 -&gt; GPS RX<br>// 3.3v -&gt;GPS 3.3v<br>// GND -&gt;GPS GND<br>#include &lt;Adafruit_GPS.h&gt;<br>#include &lt;SoftwareSerial.h&gt;</pre><pre>SoftwareSerial GPSSerial(6, 5);<br>Adafruit_GPS GPS(&amp;GPSSerial);<br>uint32_t timer = millis();</pre><pre>void setup() {<br> Serial.begin(115200); // initialize serial</pre><pre>// — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — <br> // Initialize LoRa<br> Serial.println(“LoRa Duplex Init”);<br> LoRa.setPins(csPin, resetPin, irqPin); // set CS, reset, IRQ pin</pre><pre>if (!LoRa.begin(433E6)) { // 915E6)) { // initialize ratio at 915 MHz<br> Serial.println(“Error LoRa init failed”);<br> while (true);<br> }</pre><pre>LoRa.setSyncWord(syncWord);<br> LoRa.setSpreadingFactor(spreadingFactor);<br> LoRa.setTxPower(20, true);<br> LoRa.setTimeout(10); //set Stream timeout of 10ms<br> Serial.println(“LoRa init succeeded”); //set the I/O pin modes:</pre><pre>// — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —<br> // Initialize Accelerometer<br> Serial.println(“Accelerometer Init”);<br> Wire.begin(accelerometerIC2Address);</pre><pre>//Begin communication over I2C<br> if (myAdxl.begin() == false) {<br> Serial.println(“Error accelerometer init failed”);<br> while(1);<br> }</pre><pre>Serial.print(“Accelerometer init succeeded”);<br> myAdxl.measureModeOn(); // wakes up the sensor from standby and put it into measurement mode</pre><pre>// — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — <br> // Initialize GPS<br> Serial.println(“GPS Software Serial”);<br> GPS.begin(9600);<br> // uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude<br> GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);<br> // uncomment this line to turn on only the “minimum recommended” data<br> //GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);<br> // For parsing data, we don’t suggest using anything but either RMC only or RMC+GGA since<br> // the parser doesn’t care about other sentences at this time</pre><pre>// Set the update rate<br> GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate<br> // For the parsing code to work nicely and have time to sort thru the data, and<br> // print it out we don’t suggest using anything higher than 1 Hz</pre><pre>// Request updates on antenna status, comment out to keep quiet<br> GPS.sendCommand(PGCMD_ANTENNA);</pre><pre>delay(1000);<br> // Ask for firmware version<br> GPSSerial.println(PMTK_Q_RELEASE);</pre><pre>Serial.println(“Setup Complete”);<br> Serial.flush();<br>}</pre><pre>int counter = 0;</pre><pre>void sendData(String name, String value) {<br> String packet = “,” + name + “,” + value;<br> Serial.print(packet);<br> LoRa.print(packet);<br>}</pre><pre>void loop() {<br> char c = GPS.read();</pre><pre>if ©<br> Serial.write(c);</pre><pre>// if a sentence is received, we can check the checksum, parse it…<br> if (GPS.newNMEAreceived()) {<br> // a tricky thing here is if we print the NMEA sentence, or data<br> // we end up not listening and catching other sentences!<br> // so be very wary if using OUTPUT_ALLDATA and trytng to print out data<br> //Serial.println(GPS.lastNMEA()); // this also sets the newNMEAreceived() flag to false</pre><pre>if (!GPS.parse(GPS.lastNMEA())) { // this also sets the newNMEAreceived() flag to false<br> Serial.println(“GPS FAILED”);<br> return; // we can fail to parse a sentence in which case we should just wait for another<br> }<br> }</pre><pre>if (!myAdxl.dataReady()) {// check data ready interrupt, note, this clears all other int bits in INT_SOURCE reg<br> Serial.println(“Waiting for dataReady.”);<br> }<br> else {<br> myAdxl.readAccel();</pre><pre>// send packet<br> LoRa.beginPacket();<br> LoRa.print(“BEGIN,”);<br> sendData(“id”, String(counter));<br> sendData(“src”, String(localAddress));<br> sendData(“dest”, String(destinationAddress));<br> sendData(“x”, String(myAdxl.x));<br> sendData(“y”, String(myAdxl.y));<br> sendData(“z”, String(myAdxl.z));<br> sendData(“day”, String(GPS.day, DEC));<br> sendData(“month”, String(GPS.month, DEC));<br> sendData(“year”, String(GPS.year, DEC));<br> sendData(“fix”, String((int)GPS.fix));<br> sendData(“quality”, String((int)GPS.fixquality));</pre><pre>if (GPS.fix) {<br> sendData(“latitude”, String(GPS.latitude, 4));<br> sendData(“lat”, String(GPS.lat));<br> sendData(“longitude”, String(GPS.longitude, 4));<br> sendData(“long”, String(GPS.lon));<br> sendData(“knots”, String(GPS.speed));<br> sendData(“angle”, String(GPS.angle));<br> sendData(“altitude”, String(GPS.altitude));<br> sendData(“satellites”, String((int)GPS.satellites));<br> }<br> LoRa.print(“,END”);<br> Serial.println();<br> LoRa.endPacket();<br> }</pre><pre>counter++;<br> delay(50);<br>}</pre><pre><a href="https://github.com/chrisbensen/chris-blogs/blob/main/WeekendHacks/rocket/files/pi/lora.py">lora.py</a><br><br>import time<br>import busio<br>from digitalio import DigitalInOut, Direction, Pull<br>import board<br>import adafruit_rfm9x<br>import requests<br>import os<br>import json</pre><pre>URL = os.getenv(‘URL’)<br>print(URL)</pre><pre>if (URL is None):<br> print(“URL environment variable not found”)</pre><pre>flight_file = open(“lora.log”, “a+”)</pre><pre># Configure LoRa Radio<br>CS = DigitalInOut(board.CE1)<br>RESET = DigitalInOut(board.D25)<br>spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)<br>rfm9x = adafruit_rfm9x.RFM9x(spi, CS, RESET, 433.0)#915.0)<br>rfm9x.tx_power = 23</pre><pre>def get_val(data, name):<br> index = data.index(name)</pre><pre>if index != None:<br> return data[index + 1]</pre><pre>return None</pre><pre>def make_json(data, fields):<br> result = {}</pre><pre>for i in range(len(fields)):<br> name = fields[i]<br> result[name] = get_val(data, name)</pre><pre>return result</pre><pre>while True:<br> packet = None<br> rssi = rfm9x.last_rssi</pre><pre># check for packet rx<br> packet = rfm9x.receive(with_header=True)<br> if packet is None:<br> print(“waiting”)<br> else:<br> try:<br> print(packet)<br> packet_text = str(packet, “ascii”)<br> print(packet_text)<br> data = packet_text.split(“,”)<br> print(data)</pre><pre>print(get_val(data, “x”), get_val(data, “y”), get_val(data, “z”))</pre><pre>fields = [‘id’, ‘x’, ‘y’, ‘z’]<br> j = make_json(data, fields)<br> j[“signal”] = “{0} dB”.format(rssi)</pre><pre>if (URL is not None):<br> response = requests.post(URL, json = j)</pre><pre>flight_file.write(json.dumps(j))<br> flight_file.write(“,\n”)<br> except:<br> print(“except”)</pre><p>Copy lora.py to your Pi.</p><h3>Cloud</h3><p>Run with python3 lora.py. If you create the environment variable export URL=&lt;endpoint&gt; all the data will be streamed to the REST endoint. This requires an Oracle Cloud account. You can get one here: <a href="https://medium.com/oracledevs/create-an-oracle-always-free-cloud-account-bc6aa82c1397">Free Tier Account</a>.</p><p>Stay tuned for future directions how to set up the cloud for streaming.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fc081eb0fd03" width="1" height="1" alt=""><hr><p><a href="https://medium.com/oracledevs/project-kessel-run-fc081eb0fd03">Project Kessel Run</a> was originally published in <a href="https://medium.com/oracledevs">Oracle Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Create a Personal File Drop]]></title>
            <link>https://chrisbensen.medium.com/create-a-personal-file-drop-1ab2ed0fb86b?source=rss-279db4a5cf86------2</link>
            <guid isPermaLink="false">https://medium.com/p/1ab2ed0fb86b</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[oracle-cloud]]></category>
            <category><![CDATA[secure-file-sharing]]></category>
            <dc:creator><![CDATA[Chris Bensen]]></dc:creator>
            <pubDate>Thu, 17 Mar 2022 22:11:51 GMT</pubDate>
            <atom:updated>2022-11-07T16:13:23.248Z</atom:updated>
            <content:encoded><![CDATA[<p>By <a href="https://twitter.com/chrisbensen">Chris Bensen</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lAtyGmN_7RCW61QmblJRVA.jpeg" /><figcaption><a href="https://www.pexels.com/photo/photo-of-water-drop-3587015/">Photo by Damir Mijailovic from Pexels</a></figcaption></figure><p>If you prefer you can read this blog post on Medium <a href="https://github.com/chrisbensen/chris-blogs/blob/main/WeekendHacks/filedrop/filedrop.md">here</a>.</p><p>Have you ever wanted to share a file with someone, but it contained sensitive information? Many people think email is secure, but it isn’t. There are services, like DropBox and Google Drive, but who knows what happens with that file after you delete itm as you really don’t have full control. Here is a mechanism that I personally use that is <strong><em>security through serious obscurity</em></strong> and it is a one-time download. Let’s get started!</p><h4>Prerequisites</h4><p>1. Set up a <a href="https://medium.com/chrisbensen/create-a-simple-python-web-server-on-oci-1d3634a1d7c2">web server</a>.</p><p>Find out more about <a href="https://docs.oracle.com/en-us/iaas/Content/Compute/home.htm?source=:so:bl:or:awr:odv:::RC_WWMK220120P00034:&amp;SC=:so:bl:or:awr:odv:::RC_WWMK220120P00034:&amp;pcode=WWMK220120P00034">Compute</a> and other <a href="https://docs.oracle.com/en-us/iaas/Content/GSG/Concepts/baremetalintro.htm?source=:so:bl:or:awr:odv:::RC_WWMK220120P00034:&amp;SC=:so:bl:or:awr:odv:::RC_WWMK220120P00034:&amp;pcode=WWMK220120P00034">Oracle Cloud documentation</a> <a href="https://docs.oracle.com/en-us/iaas/Content/GSG/Concepts/baremetalintro.htm?source=:so:bl:or:awr:odv:::RC_WWMK220120P00034:&amp;SC=:so:bl:or:awr:odv:::RC_WWMK220120P00034:&amp;pcode=WWMK220120P00034">here</a>. For interactive support and community check out Oracle’s public <a href="https://oracledevrel.slack.com/join/shared_invite/zt-uffjmwh3-ksmv2ii9YxSkc6IpbokL1g#/shared-invite/email">Slack channel</a> for developers.</p><h4>Set up File Drop</h4><p>1. Now that you have all the prerequisites set up for a web server, instead of running server.py we’re going to use filedrop.py. Copy filedrop.py to your Compute instance:</p><p>scp filedrop.py opc@${INSTANCE_IP}:/home/opc</p><blockquote><a href="https://github.com/chrisbensen/chris-blogs/blob/main/WeekendHacks/filedrop/files/filedrop.py">filedrop.py</a></blockquote><pre># Python 3 file drop example<br>    # Run: python3 server.py<br>    from http.server import BaseHTTPRequestHandler, HTTPServer<br>    import time<br>    import os<br>    import argparse</pre><pre>parser = argparse.ArgumentParser(description=&quot;File drop.&quot;)<br>    parser.add_argument(&quot;ip&quot;, type=str)<br>    parser.add_argument(&quot;port&quot;, type=int, default=2022)<br>    parser.add_argument(&quot;filename&quot;, type=str)<br>    parser.add_argument(&quot;droppath&quot;, type=string)<br>    parser.add_argument(&quot;dropname&quot;, type=string)<br>    parser.add_argument(&quot;dropvalue&quot;, type=string)<br>    args = parser.parse_args()</pre><pre>address = (args.ip, args.port)<br>    filename = args.filename<br>    droppath = args.droppath<br>    dropname = args.dropname<br>    dropvalue = args.dropvalue</pre><pre>print(&quot;IP=&quot; + args.ip)<br>    print(&quot;Port=&quot; + str(args.port))<br>    if os.path.exists(filename):<br>  print(&quot;Filename=&quot; + filename)<br>    print(&quot;Path=&quot; + droppath)<br>    print(&quot;Name=&quot; + dropname)<br>    print(&quot;Value=&quot; + dropvalue)</pre><pre>class MyServer(BaseHTTPRequestHandler):<br>    def do_GET(self):<br>        self.send_response(200)<br>        self.send_header(&quot;Content-type&quot;, &quot;application/octet-stream&quot;)<br>        self.send_header(&quot;Content-Disposition&quot;, &quot;attachment; filename=&quot; + filename)<br>        self.end_headers()</pre><pre>path = self.path<br>        name = &quot;&quot;<br>        value = &quot;&quot;</pre><pre>if &#39;?&#39; in path:<br>          path, args = path.split(&#39;?&#39;, 1)<br>          name, value = args.split(&#39;=&#39;, 1)</pre><pre>if path == &quot;/&quot; + droppath and name == dropname and value == dropvalue:<br>            fo = open(filename, &quot;rb&quot;)<br>            self.wfile.write(fo.read())<br>            fo.close()<br>            print(&quot;success&quot;)</pre><pre>os.remove(filename)</pre><pre>print(path, name, value)<br>        return</pre><pre>if __name__ == &quot;__main__&quot;:<br>    webServer = HTTPServer(address, MyServer)<br>    print(&quot;Server started http://%s:%s&quot; % address)</pre><pre>try:<br>        webServer.serve_forever()<br>    except KeyboardInterrupt:<br>        pass</pre><pre>webServer.server_close()<br>    print(&quot;Server stopped.&quot;)</pre><pre>parser = argparse.ArgumentParser(description=”File drop.”)<br> parser.add_argument(“ip”, type=str)<br> parser.add_argument(“port”, type=int, default=2022)<br> parser.add_argument(“filename”, type=str)<br> parser.add_argument(“droppath”, type=string)<br> parser.add_argument(“dropname”, type=string)<br> parser.add_argument(“dropvalue”, type=string)<br> args = parser.parse_args()</pre><pre>address = (args.ip, args.port)<br> filename = args.filename<br> droppath = args.droppath<br> dropname = args.dropname<br> dropvalue = args.dropvalue</pre><pre>print(“IP=” + args.ip)<br> print(“Port=” + str(args.port))<br> if os.path.exists(filename):<br> print(“Filename=” + filename)<br> print(“Path=” + droppath)<br> print(“Name=” + dropname)<br> print(“Value=” + dropvalue)</pre><pre>class MyServer(BaseHTTPRequestHandler):<br> def do_GET(self):<br> self.send_response(200)<br> self.send_header(“Content-type”, “application/octet-stream”)<br> self.send_header(“Content-Disposition”, “attachment; filename=” + filename)<br> self.end_headers()</pre><pre>path = self.path<br> name = “”<br> value = “”</pre><pre>if ‘?’ in path:<br> path, args = path.split(‘?’, 1)<br> name, value = args.split(‘=’, 1)</pre><pre>if path == “/” + droppath and name == dropname and value == dropvalue:<br> fo = open(filename, “rb”)<br> self.wfile.write(fo.read())<br> fo.close()<br> print(“success”)</pre><pre>os.remove(filename)</pre><pre>print(path, name, value)<br> return</pre><pre>if __name__ == “__main__”:<br> webServer = HTTPServer(address, MyServer)<br> print(“Server started http://%s:%s&quot; % address)</pre><pre>try:<br> webServer.serve_forever()<br> except KeyboardInterrupt:<br> pass</pre><pre>webServer.server_close()<br>print(“Server stopped.”)</pre><p>1. Collect a few variables:</p><p>**INSTANCE_IP** — You have this from the web server prerequisite earlier.<br> **Port** — You have this from the web server prerequisite earlier.<br> **Filename** — This is the file that you want to share.<br> **PathToFile** — This is where the file is located on the compute instance.<br> **Name** — This is just a random string that you will come up with.<br> **Value** — Same as Name above.<br> **PrivateIP** — This is the private IP address of your server.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/437/1*ez6yB8V8kUiAwrDyunO1Qg.png" /></figure><p>1. Copy your file to the compute instance:<br> scp -i ~/.ssh/oci_id_rsa foo.zip opc@${INSTANCE_IP}:/home/opc</p><p>1. run the server<br> sudo python3 filedrop.py &lt;PrivateIP&gt; &lt;Port&gt; &lt;Filename&gt; &lt;PathToFile&gt; &lt;Name&gt; &lt;Value&gt; &amp;</p><p>For example:<br> scp foo.zip ocp@1.2.3.4:/home/pi<br> sudo python3 filedrop.py 1.2.3.4 8100 foo.zip chris knockknock whothat &amp;</p><p>1. From any computer use a web browser and access the url http://&lt;YourPublicIP&gt;:&lt;Port&gt;/PathToFile?Name=Value to download the file.</p><p>For Example:<br> http://&lt;YourPublicIP&gt;:8100/chris/foo.zip?knockknock=whothat</p><p>The file will be downloaded, and then deleted from the VM. If any attempt to access the wrong URL occurs the file will be deleted. Share this URL with whomever you want to download the file.</p><p>What I find gratifying: I can send the URL in pieces and the other person must assemble it correctly, but if they fail the file will be deleted. This can be a pain, so I usually have a phone call if I choose this option. I trust “security through obscurity” in this limited case, but I prefer for it to be as real-time as possible. It’s your choice, but thought I’d share because sending confidiential information over email is not a good idea.</p><p>If you have any questions or for interactive support and community check out Oracle’s public <a href="https://bit.ly/devrel_slack">Slack channel</a> for developers.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1ab2ed0fb86b" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>