<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: David Muckle</title>
    <description>The latest articles on DEV Community by David Muckle (@dvdmuckle).</description>
    <link>https://dev.to/dvdmuckle</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2064%2F6cc8348a-7039-4d50-8365-f7b0aa626248.jpg</url>
      <title>DEV Community: David Muckle</title>
      <link>https://dev.to/dvdmuckle</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dvdmuckle"/>
    <language>en</language>
    <item>
      <title>A Tale of Two Build Systems: Launchpad and Copr</title>
      <dc:creator>David Muckle</dc:creator>
      <pubDate>Thu, 19 Aug 2021 13:00:00 +0000</pubDate>
      <link>https://dev.to/dvdmuckle/a-tale-of-two-build-systems-launchpad-and-copr-59p1</link>
      <guid>https://dev.to/dvdmuckle/a-tale-of-two-build-systems-launchpad-and-copr-59p1</guid>
      <description>&lt;p&gt;Whoa, a blog post! Haven’t written one of those in a while. I’ll make another one to go over what’s happened since my last post, but right now, let’s focus on something very specific: package managers, and the build systems that support them. It’s Ubuntu vs Fedora, RPM vs DEB, apt vs dnf (or yum), Launchpad vs Copr.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fedora and Copr
&lt;/h2&gt;

&lt;p&gt;Let’s start off at the beginning. I use Fedora on my desktop and personal laptop. It’s great! I like how cutting edge yet stable everything is. But before that I used Ubuntu. And that’s probably the case with a lot of other people. Ubuntu is very popular and easy to get started with, and because of that there’s a lot of guides for how to use it and how to install things. Its popularity has basically grown because of its popularity, in short. There’s so many flavors and distros based on Ubuntu too. Ubuntu and Fedora both have something in common as well: the groups behind them both have a platform that lets you build and host packages for them. Ubuntu has Launchpad, and the PPA, or Personal Package Archive, and Fedora has Copr.&lt;/p&gt;

&lt;p&gt;Let’s start chronologically for me. I first used Copr… Four years ago? It’s been a bit, and I’m decently familiar with it. There are a handful of tools you can use to build an RPM package. RPM is the packaging format that Fedora and related distros use. To start, you have to write a spec file. This file can be pretty simple, or very large, but what it’s responsible for is describing what your package is, how to build it, and where all the files to install are located. Here’s an example of one I made a while back.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;%define name minsh
%define build_timestamp %{lua: print(os.date("%Y%m%d"))}
%define version 1.9.1
Name: %{name}       
Version: %{version} 
Release: %{build_timestamp}%{?dist}
Summary: A very simple shell    
Source0: https://github.com/dvdmuckle/minsh/archive/master.tar.gz#/%{name}-%{version}-%{release}.tar.gz
License: GPLv3
Packager: David Muckle &amp;lt;dvdmuckle@dvdmuckle.xyz&amp;gt;
BuildRequires: gcc make

%description

A very simple shell that supports running commands and output redirection.
%global debug_package %{nil}
%prep
%autosetup -n %{name}-master

%build
make 

%install
mkdir %{buildroot}%{_bindir} -p
install -s minsh.o %{buildroot}%{_bindir}/minsh

%clean
rm -rf %{buildroot}

%files
%{_bindir}/minsh
%doc

%changelog

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a spec for a small shell in C I wrote in college. I got the actual class project itself done in an afternoon, and had some time to package it up before the thing was due. Thus, this is pretty simple. The spec describes where you can get the code to build this under &lt;code&gt;Source0&lt;/code&gt;, what prep work needs to be done to build it, what building it looks like, what installing it looks like, and where the other files are. For this, there’s only one file, the binary. This also describes the tools requires to build the package. Note this doesn’t include any runtime dependencies. There technically are some, but they’re all libraries included in &lt;code&gt;libc&lt;/code&gt; which is a library package that’s just about always installed on any system.&lt;/p&gt;

&lt;p&gt;In order to use this spec file to build your RPM, there are a few ways. Back then, I used &lt;code&gt;spectool&lt;/code&gt; and &lt;code&gt;rpmbuild&lt;/code&gt;, and &lt;code&gt;builddep&lt;/code&gt;. &lt;code&gt;spectool&lt;/code&gt; lets you lint the spec file and get the sources, &lt;code&gt;rpmbuild&lt;/code&gt; does the actual building, and &lt;code&gt;builddep&lt;/code&gt; lets you make sure all your build dependencies are installed. One of the cool things you can build is something called an SRPM, which is basically this spec file and your sources wrapped into a fancy archive file. It’s an RPM waiting to happen, just add water! Or a build system! Or, you can take another route and use &lt;code&gt;mock&lt;/code&gt;, which is very nice as it will build your package in a chroot and manage all your build dependencies for you. Instead of having to remember two tools and the flags needed to do what you want, you can use one tool. And you can build for multiple OSes! So long as they use RPM, that is. This tool is more or less the same as what Copr does, so it’s a great way to make sure your build will work on Copr.&lt;/p&gt;

&lt;p&gt;Copr is the first build system I used. You can feed it either a spec or an SRPM, either uploaded directly or cloned from a git repo. It’ll get your source (or use the one in the SRPM you uploaded), get all the dependencies in order, execute your instructions, and upload the resulting package to a repo anyone can add to their system. The most important detail is building an RPM is pretty flexible. Sure, there are some standards, but if you break the rules things usually won’t fail outright. For example, let’s say you want to build a binary written in Golang. It’s 2021, you probably have a &lt;code&gt;go.mod&lt;/code&gt; file, right? One that specifies all your dependencies? And a &lt;code&gt;go.sum&lt;/code&gt; file that specifies the versions of those dependencies, right? So why manage those dependencies in the spec file as well? With Copr you can run a build with internet access, which allows for you to pop a &lt;code&gt;go mod vendor&lt;/code&gt; into your build instructions, so your dependencies are satisfied. This is technically against the packaging “code” for Fedora packages, but, well…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CQg9aXrV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/ry_sCXk6wH0AAAAC/pirates-caribbean-code.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CQg9aXrV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/ry_sCXk6wH0AAAAC/pirates-caribbean-code.gif" alt="Pirates of the Caribbean GIF of Captain Barbosa talking about how &amp;quot;the code is more what you'd call guidelines, than actual rules&amp;quot;"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s important to note that both Fedora and Debian/Ubuntu have standards for packaging. These standards are more for if your package is going to be published in one of their repositories, but it’s still useful to keep the standards in mind.&lt;/p&gt;

&lt;p&gt;One final thing before we move on from Copr is that with Copr, you can specify the versions of Fedora (and friends) as well as the architectures you want your package to be built for with just a check of a checkbox. And you only need one spec written! Generally speaking Fedora packages don’t change names or anything between versions, so this shouldn’t break any of your build and runtime dependencies.&lt;/p&gt;

&lt;p&gt;… Okay one last &lt;em&gt;last&lt;/em&gt; thing and then we move on to Debian packaging. Spec files also allow you to put dynamic stuff into the file. Notice how the &lt;code&gt;build_timestamp&lt;/code&gt; uses some Lua to get the current time? What a pain it would be to specify that manually every time! There’s also probably a macro for that too! There’s a number of packages that Fedora supplies that include macros, which can be useful for building things such as Golang-based packages. (Wow all this talk of Golang, you’d think I had &lt;a href="https://github.com/dvdmuckle/spc"&gt;some kind of Golang project I’ve been working on packaging…&lt;/a&gt;). These macros can do a whole slew of things including specifying how your package is built and where any binaries are installed. The downside to that is unless you know what precisely the macro does, it can be hard to debug when something goes wrong, and to an outside observer it can be hard to figure out what’s going on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ubuntu/Debian and Launchpad
&lt;/h2&gt;

&lt;p&gt;Okay! Now on to Debian packaging. This is going to be a lot of me saying “I don’t know what this is exactly,” because I literally figured this out a day ago. I am going to figure out a lot of that though, and probably publish an addendum post to this, so a lot of my opinions will probably also change, but for now this is a lot of “This is what I had to do to get this working.”&lt;/p&gt;

&lt;p&gt;As previously stated, there’s a handful of tools to build a DEB package. Which is a lot compared to the maybe four or so tools for RPM. You can even use &lt;code&gt;dpkg&lt;/code&gt;, the package manager for DEB, to build packages! This is largely a bad idea because it literally creates an archive you can install, with nothing else involved, and assumes a lot like that your binary will run on other systems with potentially different library versions. Cool you can do it, though. As an aside, while &lt;code&gt;dpkg&lt;/code&gt; is the actual package manager used by Debian based systems, and thus Ubuntu, usually it’s used via &lt;code&gt;apt&lt;/code&gt; or &lt;code&gt;apt-get&lt;/code&gt;. Debian based systems also have their own version of &lt;code&gt;mock&lt;/code&gt; system, called &lt;code&gt;pbuilder&lt;/code&gt;… and also &lt;code&gt;cowbuilder&lt;/code&gt;??? One uses the other under the hood, I think, but I couldn’t get either of them working, but either way, they both build in a chroot and are in theory a good way to build for multiple distro versions.&lt;/p&gt;

&lt;p&gt;For the package I built, I ended up using a combination of &lt;code&gt;debuild&lt;/code&gt; and &lt;code&gt;dpkg-buildpackage&lt;/code&gt;. Technically speaking they can both generate the same files you need for Launchpad, so I ended up with &lt;code&gt;debuild&lt;/code&gt; since it requires fewer command line arguments. &lt;code&gt;debuild&lt;/code&gt; also uses &lt;code&gt;dpkg-buildpackage&lt;/code&gt; and the like under the hood along with some other linting stuff. To generate all the files to actually build this package, I used &lt;code&gt;dh-make-golang&lt;/code&gt;. This is related to &lt;code&gt;dh-make&lt;/code&gt;, which basically allows you to provide some things like your package’s name, what kind it is, and some other arguments to generate all of those files you need to build your package. And there’s, uh, more than just one, compared to RPM. At least they all go into the same &lt;code&gt;debian&lt;/code&gt; directory…&lt;/p&gt;

&lt;p&gt;Let’s start alphabetically. You’ve got your &lt;code&gt;changelog&lt;/code&gt; file that has some very specific formatting to do a couple things. It lists your current and past versions for your package, as well as, well, your changelog, and what distro you’re building for. I think the distro part can be templated out so when the time comes to send generate the files to send to Launchpad, you can have one changelog for multiple distros. For now I’m just building for Ubuntu 20.04 since it’s the latest LTS release. The formatting here is so specific there’s a command just for updating the changelog, &lt;code&gt;dch&lt;/code&gt;, that will do things like put the date in there correctly, bump the version number, and put in your email.&lt;/p&gt;

&lt;p&gt;Your &lt;code&gt;control&lt;/code&gt; file will list all of the metadata about your package. What it’s called, the maintainer, any build dependencies. One weird oddity I ran into is the package that enables shell completion in Ubuntu, &lt;code&gt;bash-completion&lt;/code&gt;, also provides the files required to implement shell completion when building a package. Which is a little weird, initially I thought the package to allow for this would be some kind of package specific to building packages, much like the macros packages in Fedora.&lt;/p&gt;

&lt;p&gt;The last major file (There are many others but they’re things like &lt;code&gt;copyright&lt;/code&gt; which includes licensing stuff, and a couple other things I don’t even remember generating.) is the &lt;code&gt;rules&lt;/code&gt; file. If you’re familiar with &lt;code&gt;make&lt;/code&gt;, this will probably look familiar. It’s a Makefile! And it’s executable, but it gets executed by some other helper programs, so maybe don’t try executing it yourself if you’re new to this. This file is basically where you define how to go from source to binary for your package, and will probably also utilize an existing Makefile you already have. My &lt;code&gt;rules&lt;/code&gt; file… does not do that, it uses a &lt;code&gt;dh&lt;/code&gt; command with some other Golang-specific flags to build my binary, so I don’t know entirely what it does. What I do know is I had to add the &lt;code&gt;--with=bash-completion&lt;/code&gt; flag and then add a &lt;code&gt;spc.bash-completion&lt;/code&gt; file with all the shell completion stuff. Remember how I said macros can complicate things and make it hard to figure out what’s happening? Well the shoe’s on the other foot now. I clearly have a lot of learning to do in terms of how Debian packaging works, but what I do want to share are a couple gripes I’ve run into thus far.&lt;/p&gt;

&lt;h2&gt;
  
  
  Miscellaneous Headaches
&lt;/h2&gt;

&lt;p&gt;At first I ran into some issues with building the files necessary for Launchpad because it didn’t want to allow uncommited files in my repository when creating the source archive. Well, tough cookies, I need to include my vendored Golang libraries, because according to my research Launchpad doesn’t allow for building with internet access, so it can’t go off and get the necessary files for me to build. Copr can do builds with internet access, so while it would be cool for Launchpad to do that, I get why they may want to disallow it. At the time I was using &lt;a href="https://people.debian.org/~stapelberg/2015/07/27/dh-make-golang.html"&gt;this&lt;/a&gt; guide to &lt;code&gt;dh-make-golang&lt;/code&gt; in order get it working, which uses a couple other different tools later on in order to do the actual package build. I don’t need to do a full package build, however, I just need to generate the Debian equivalent of a SRPM, so I checked out a couple other tools. Eventually I settled on &lt;code&gt;debuild&lt;/code&gt;, which lets me build just my source and other files, most of which are variants on the above files, sign things with my GPG key, and also ignore that I don’t have my build dependencies installed, since those include library packages I don’t need.&lt;/p&gt;

&lt;p&gt;This was another pain point. Launchpad has a &lt;em&gt;heavy&lt;/em&gt; reliance on GPG keys. You have to upload the public key to Ubuntu’s keyserver, then import it to Launchpad. The whole process can take anywhere from thirty minutes to an hour. It’s &lt;em&gt;slow&lt;/em&gt;. Granted we’re talking about Ubuntu infrastructure, infrastructure supporting one of if not the most popular Linux distro on the planet, so I get why it might be slow. Still, it’s hard to not be annoyed. On top of that, once you get the build going, it can take a few minutes after it’s completed for the DEB package to be available in the PPA. With Copr, it’s available nearly immediately, and there’s no need to use GPG keys for authentication. For both systems, keys will be generated for the package repository itself, so the GPG key you use with Launchpad, as far as I can tell, is only use to authenticate you and your files when you use &lt;code&gt;dput&lt;/code&gt; to upload to Launchpad. This operation is apparently straight-up FTP. Also, if you screw up the GPG stuff from earlier, you can end up in a position where your Launchpad build fails silently and you can’t reuse that version for a build, and will be forced to increment the build number and rebuild.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;That all being said… I did it! I solved for Launchpad! Now I can focus on automating all of this with GitHub actions, something I’m not completely looking forward to. Overall, these two build systems allow you to do some neat stuff and make it very user friendly to install a package that isn’t in the main repositories. The way it gets to there, however, is very different. Debian package builds have a lot of rules and certain ways you have to do things, in addition to having many tools that do the same thing in ever so slightly different ways. Debian packaging also has documentation of mixed quality. The basics are well documented, but trying to do something a little more exotic like using &lt;code&gt;dh-make-golang&lt;/code&gt; isn’t as documented as I would have liked. Fedora packaging has a handful of useful tools, with mostly up to date documentation to boot. The vibe I get from these build systems is they tend to reflect the OS you can build for. Fedora is cutting edge while being solid and pretty user friendly, whereas Ubuntu is incredibly well supported but, at least for LTS releases, you may not be getting the latest thing. Again, this is all my opinion as someone new to Launchpad and only decently knowledgeable with RPM packages. I’ll do more research into how to do a lot of these things, but this has been my journey thus far.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://dvdmuckle.xyz/index.php/2021/08/19/a-tale-of-two-build-systems-launchpad-and-copr/"&gt;A Tale of Two Build Systems: Launchpad and Copr&lt;/a&gt; appeared first on &lt;a href="https://dvdmuckle.xyz"&gt;dvdmuckle&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>copr</category>
      <category>fedora</category>
      <category>launchpad</category>
      <category>ubuntu</category>
    </item>
    <item>
      <title>When Not Getting the Job Is Just As Fine</title>
      <dc:creator>David Muckle</dc:creator>
      <pubDate>Mon, 07 May 2018 00:53:16 +0000</pubDate>
      <link>https://dev.to/dvdmuckle/when-not-getting-the-job-is-just-as-fine-2a27</link>
      <guid>https://dev.to/dvdmuckle/when-not-getting-the-job-is-just-as-fine-2a27</guid>
      <description>&lt;p&gt;Recently I had applied for a DevOps position at a startup. I was approached by a company recruiter on LinkedIn to apply for the position. I'm a graduating college senior, and the position expected at least three years in DevOps. I know little about AWS, but I do know a decent amount about Kubernetes. I applied, knowing I would probably not not get the position, but hoping I might.&lt;/p&gt;

&lt;p&gt;I was shortly scheduled for a phone screening. Before I even got to the phone screening, I went to a Kubernetes meetup the day before. One of the speakers works at the same company I applied to. He also said he was working with a recruiter to get more DevOps people in the company. Wait a second... I went up to him after his presentation and said I was approached by a recruiter from his company for this position. Turns out, besides being the DevOps lead, he was also the hiring manager for this position! We talked a bit, but he was headed out the door by then and I didn't want to keep him.&lt;/p&gt;

&lt;p&gt;The recruiter mentioned this chance encounter during the phone screening the next day, and eventually I had a video interview with the hiring manager I met at the meetup. We talked a bit about my experience, and went over some technical questions.&lt;/p&gt;

&lt;p&gt;I was very surprised when a couple days later I was asked to come to the office to talk to some more people. This was a first for me, so I graciously accepted while stressing over what to wear. The onsite came and went. Most of the questions were more about company fit, with a couple tangential conversations on things ranging from the movie &lt;em&gt;Hackers&lt;/em&gt; to vinyl records and 70s prog rock. I was very impressed with what the company had to offer, and I hoped they were equally impressed with what I could offer too.&lt;/p&gt;

&lt;p&gt;The last person I talked with was the hiring manager. He mentioned that a lot of what I would have to do on the job I would be learning as I went because of my skill level. I said, having been in school for the past few years, that's nothing new. He mentioned a lot of it would have to be learning on my own. I said that a lot of what I knew about Kubernetes and distributed computing was all stuff I had learned on my own, as there aren't any classes for that. We went over the company stack and some issues they had solved recently, he showed me the lab, then showed me the door.&lt;/p&gt;

&lt;p&gt;I heard back a couple days later from the hiring manager. He didn't think I would be a good fit for the position because of my experience, and that, if they had an opening for a more junior position that I would be a perfect fit.&lt;/p&gt;

&lt;p&gt;Then something unexpected happened. He introduced me to a colleague at another company that is hiring for positions that would more fit my skill level, saying that I had impressed him in my interviews. He also extended a hand of mentorship.&lt;/p&gt;

&lt;p&gt;What I'm trying to get at here is, sometimes applying for a job isn't just applying for a job. It's an opportunity to make new connections, even if you don't get the job. And coming from someone still new on the scene, every connection is important.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; Just wanted to update this post to say I got the position at the other company!&lt;/p&gt;

</description>
      <category>career</category>
    </item>
    <item>
      <title>"You're overthinking it."</title>
      <dc:creator>David Muckle</dc:creator>
      <pubDate>Fri, 23 Mar 2018 20:46:49 +0000</pubDate>
      <link>https://dev.to/dvdmuckle/youre-overthinking-it-a0f</link>
      <guid>https://dev.to/dvdmuckle/youre-overthinking-it-a0f</guid>
      <description>&lt;p&gt;To preface, I am a student, so hearing this isn't too unfamiliar. But at the same time, I wonder if it's something normal to hear.&lt;/p&gt;

&lt;p&gt;I heard this the other day when trying to format printing in an interpreter I was working on. The solution was so simple that, indeed, as my friend noted, I was overthinking things. When someone says "You're overthinking it," how does it make you feel?&lt;/p&gt;

</description>
      <category>question</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Making a Racket with OpenFaaS</title>
      <dc:creator>David Muckle</dc:creator>
      <pubDate>Wed, 14 Mar 2018 16:02:39 +0000</pubDate>
      <link>https://dev.to/dvdmuckle/making-a-racket-with-openfaas--4mmf</link>
      <guid>https://dev.to/dvdmuckle/making-a-racket-with-openfaas--4mmf</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---3RhipEC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://racket-lang.org/img/racket-logo.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---3RhipEC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://racket-lang.org/img/racket-logo.svg" alt="Image result for racket lang"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cloud computing is growing, and with it a whole bunch of new frameworks and terms, such as “serverless” and “Function as a Service.” While a lot of these frameworks are supplied by big companies like Amazon and Google, there are projects such as OpenFaaS which allow you to run a Function as a Service platform on your own machine(s). What’s more, OpenFaaS also allows for easily extending the platform to support other languages. Because OpenFaaS revolves around functions, it made perfect sense to add support for the first functional programming language, Lisp, by using the wonderful Racket environment. And now you too can make your own serverless Racket function! Let's try it out.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting Up the Environment
&lt;/h3&gt;

&lt;p&gt;If you already have OpenFaaS set up, great, you can skip this section! If you have Docker on your machine already, you can skip the next paragraph. We’re going to be setting up OpenFaaS to run on Docker. If you’d like to run it on something else, check out the &lt;a href="https://docs.openfaas.com/"&gt;official documentation&lt;/a&gt;. OpenFaas supports Kubernetes and Docker Swarm. You can also use &lt;a href="http://play-with-docker.com"&gt;Play With Docker&lt;/a&gt; if you don’t want to install Docker on your local machine, and instead just want to try out OpenFaaS temporarily in an online ephemeral environment. While you don’t need it, it may help to have a &lt;a href="http://hub.docker.com"&gt;Docker Hub&lt;/a&gt; account, in the case you wish to make your function available to the rest of the world, or are going to build your function on a machine different from the one you shall deploy to.&lt;/p&gt;

&lt;h4&gt;
  
  
  Installing Docker
&lt;/h4&gt;

&lt;p&gt;Docker is a tool that allows you to build and launch containers: File system images with all the libraries and code for a given application. A Docker container can run on any machine with Docker installed, which makes it powerful for shipping and deploying applications. We’re going to use it to run and build OpenFaaS functions. If you have a Linux system, you can do &lt;code&gt;curl https://get.docker.com | bash&lt;/code&gt; or &lt;code&gt;curl -o docker.sh https://get.docker.com &amp;amp;&amp;amp; bash docker.sh&lt;/code&gt; to install Docker. Note the output of the command, especially the note about the &lt;code&gt;docker&lt;/code&gt; group. If you have a Mac, see &lt;a href="https://docs.docker.com/docker-for-mac/install/"&gt;here&lt;/a&gt; to install Docker, which installs like any other app. If you have Windows, and you don’t have the Pro version of Windows 10, you can use &lt;a href="https://docs.docker.com/toolbox/toolbox_install_windows/"&gt;Docker Toolbox&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Side Note: If you’d like a more permanent and manageable means of testing OpenFaaS, I highly suggest using &lt;a href="https://docs.docker.com/machine/"&gt;Docker Machine&lt;/a&gt; to create a VM just for OpenFaaS.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Deploying OpenFaaS
&lt;/h4&gt;

&lt;p&gt;Since OpenFaaS is designed to run in a cluster of multiple machines, we’re going to make our machine a Docker Swarm manager. It’s okay if you only have one machine for testing, but if you’d like to deploy OpenFaaS in production, it’s highly suggested to have some fault tolerant cluster with multiple machines. To make your machine a Swarm manager, you can run &lt;code&gt;docker swarm init&lt;/code&gt; or &lt;code&gt;docker swarm init --advertise-addr eth0&lt;/code&gt;, depending on the output from the former command. Now we can deploy OpenFaaS with &lt;code&gt;git clone https://github.com/openfaas/faas &amp;amp;&amp;amp; cd faas &amp;amp;&amp;amp; git checkout 0.7.5 &amp;amp;&amp;amp; ./deploy_stack.sh&lt;/code&gt;. You can see the parts of OpenFaaS spinning up with &lt;code&gt;docker service ls&lt;/code&gt;. You can now visit &lt;code&gt;http://&amp;lt;docker host ip&amp;gt;:8080&lt;/code&gt; with your web browser. If you’re running Docker on Linux or Mac, &lt;code&gt;localhost&lt;/code&gt; is your Docker host. On Windows, with Docker Toolbox, it will be some &lt;code&gt;192.168.0.0/16&lt;/code&gt; IP. You can view the IP with &lt;code&gt;docker system info | grep 'Node Address'&lt;/code&gt;.  If you’re using Play With Docker, you should see a link to port 8080 near the top of the page.&lt;/p&gt;

&lt;p&gt;From the OpenFaaS dashboard, you can deploy new functions from the function store, as well as invoke functions. You can also invoke these functions with &lt;code&gt;curl&lt;/code&gt; using &lt;code&gt;curl http://&amp;lt;docker host ip&amp;gt;:8080/function/&amp;lt;function name&amp;gt;&lt;/code&gt; or &lt;code&gt;curl -XPOST -d &amp;lt;data&amp;gt; http://&amp;lt;docker host ip&amp;gt;:8080/function/&amp;lt;function name&amp;gt;&lt;/code&gt; if the function expects some input.&lt;/p&gt;

&lt;p&gt;Now that the platform is set up, we need to to get the client tool to interact with OpenFaaS. You can do so with &lt;code&gt;curl -sL cli.openfaas.com | sh&lt;/code&gt;. This will give you the &lt;code&gt;faas-cli&lt;/code&gt; tool, which is used to build, deploy, and invoke functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating Our Racket Function
&lt;/h3&gt;

&lt;p&gt;Now that our environment is set up, we can start function creation. Create a new folder for your function, and in it run &lt;code&gt;faas-cli template pull https://github.com/dvdmuckle/racket-template&lt;/code&gt;. This will pull in skeleton code for Racket functions, as well as some supporting files. Next, run &lt;code&gt;faas-cli new &amp;lt;function name&amp;gt; --lang racket&lt;/code&gt;, where &lt;code&gt;function name&lt;/code&gt; is the name of the function you’re creating. Don’t worry about it matching the folder you created earlier.&lt;/p&gt;

&lt;p&gt;This will create a few artifacts: A folder with the name of your function, and a &lt;code&gt;&amp;lt;function name&amp;gt;.yml&lt;/code&gt; file. The YAML file specifies the name of the function, what language it is, the name of the Docker image that will be built, the URL for where you can access your OpenFaaS setup, and a few other things.  Depending on your setup, you may wish to change the value for the image, if your OpenFaaS setup isn’t on the same machine where you’ll be building your functions.&lt;/p&gt;

&lt;p&gt;In the folder that was created, you’ll find a &lt;code&gt;handler.rkt&lt;/code&gt; file. Let’s see what it has.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#lang racket
(provide handle)
(define (handle) (define in (read-line))
 (display "You said ")
 (displayln in))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While all this does is echo whatever input it receives, it gives us a good skeleton to work off of. Two things must always exist here: A language declaration, where this is using &lt;code&gt;racket&lt;/code&gt;, and &lt;code&gt;(provide handle)&lt;/code&gt;, which simply says, “This file provides this function.” This is necessary as this handler file is used by another file to grab the &lt;code&gt;handle&lt;/code&gt; function definition, which must always be present and be a top level function. Beyond that, this file can contain whatever else you want. If you’d like, you can add any more files in the same folder as &lt;code&gt;handler.rkt&lt;/code&gt;, using &lt;code&gt;require&lt;/code&gt; and &lt;code&gt;provide&lt;/code&gt; to make sure they’re all aware of each other. Note that input is gathered from &lt;code&gt;stdin&lt;/code&gt; with &lt;code&gt;read-line&lt;/code&gt;. The function will fail to build if &lt;code&gt;handle&lt;/code&gt; has any parameters.&lt;/p&gt;

&lt;p&gt;While it would be perfectly fine to build and deploy this function as is, it’s kind of boring. How about something to calculate Fibonacci numbers?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight racket"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;lang&lt;/span&gt; &lt;span class="nv"&gt;scheme&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;provide&lt;/span&gt; &lt;span class="nv"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="nv"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;read-line&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fib&lt;/span&gt; &lt;span class="nv"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fof&lt;/span&gt; &lt;span class="nv"&gt;n&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="nv"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;cond&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;n&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;n&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;#t&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fof&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;n&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;b&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="nv"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fof&lt;/span&gt; &lt;span class="nv"&gt;n&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="nv"&gt;num&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;string-&amp;gt;number&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;eof-object?&lt;/span&gt; &lt;span class="nv"&gt;in&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;error&lt;/span&gt; &lt;span class="s"&gt;"Requires input"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;in&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;number?&lt;/span&gt; &lt;span class="nv"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;displayln&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fib&lt;/span&gt; &lt;span class="nv"&gt;num&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;error&lt;/span&gt; &lt;span class="s"&gt;"Input not a number"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a tail recursive Fibonacci sequence, which we feed error-checked input. It will then print to &lt;code&gt;stdout&lt;/code&gt; the results. Note that &lt;code&gt;stdin&lt;/code&gt; and &lt;code&gt;stdout&lt;/code&gt; basically become HTTP data POSTs and response bodies respectively once the function is built and deployed. This is part of what makes OpenFaaS rather nifty. You can create web-based functions without having to worry about the web part, just the function part.&lt;/p&gt;

&lt;p&gt;If you have a local Racket environment, you can test this function by loading it into a Racket session, and calling the function that way. But, because I like to fly by the seat of my pants, we’re going to build this and deploy it now.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building and Deploying the Function
&lt;/h3&gt;

&lt;p&gt;Once your function is all set up, we can build it. Use &lt;code&gt;faas-cli build -f &amp;lt;function name&amp;gt;.yml&lt;/code&gt; to build the function. Make sure you made any necessary edits to the YAML file, such as changing the image value, before you build. If you’re building on and deploying to the same machine, this doesn’t matter. Now that your function is built, you can deploy it with &lt;code&gt;faas-cli deploy -f &amp;lt;function name&amp;gt;.yml --gateway http://&amp;lt;docker host ip&amp;gt;:8080&lt;/code&gt;. If you already edited the gateway value in the YAML file, you can leave out the &lt;code&gt;--gateway&lt;/code&gt; flag. You can also leave it out if the default value, &lt;code&gt;http://localhost:8080&lt;/code&gt;, is indeed where OpenFaaS is.&lt;/p&gt;

&lt;p&gt;Now, time to see the fruits of our labor! First, try &lt;code&gt;curl -XPOST -d 3 http://&amp;lt;docker host ip&amp;gt;:8080/function/&amp;lt;function name&amp;gt;&lt;/code&gt;. If your function does indeed calculate the Fibonacci number of a given number, you should get &lt;code&gt;2&lt;/code&gt; back. You can also try this out in the OpenFaaS UI which you opened before. A new function will be present, your function! You can put in the same input there, invoke it, and get the same response. You can also use &lt;code&gt;faas-cli invoke &amp;lt;function name&amp;gt; --gateway http://&amp;lt;docker host ip&amp;gt;:8080&lt;/code&gt; to call your function&lt;/p&gt;

&lt;h3&gt;
  
  
  What’s Next?
&lt;/h3&gt;

&lt;p&gt;Now that you’ve seen how you can create serverless Racket functions, I’d suggest creating more! Lisp, and Racket, are both excellent in my opinion, and I personally wish to continue adding more features to this template, such as installing external Racket libraries. Lisp as a language may seem syntactically dense at first with all its parenthesis, but stick with it long enough and you’ll soon see its brilliance. Or maybe you’ll just end up seeing parenthesis in your sleep…&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://dvdmuckle.xyz/index.php/2018/03/14/making-a-racket-with-openfaas/"&gt;Making a Racket with OpenFaaS&lt;/a&gt; appeared first on &lt;a href="https://dvdmuckle.xyz"&gt;dvdmuckle&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>lisp</category>
      <category>openfaas</category>
      <category>serverless</category>
      <category>racket</category>
    </item>
    <item>
      <title>Explain DHCP Like I'm Five</title>
      <dc:creator>David Muckle</dc:creator>
      <pubDate>Tue, 23 Jan 2018 20:31:53 +0000</pubDate>
      <link>https://dev.to/dvdmuckle/explain-dhcp-like-im-five-3ne</link>
      <guid>https://dev.to/dvdmuckle/explain-dhcp-like-im-five-3ne</guid>
      <description>&lt;p&gt;I've been having trouble with a little RPI Kubernetes cluster on my school's network, and I think the issue has to do with DHCP. Problem is, I don't really understand a whole lot of networking stuff, let alone DHCP. Could anyone ELI5?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EDIT&lt;/strong&gt;: &lt;del&gt;Thanks to the help of the campus "networking guy," I believe we've fixed the issue. Apparently wired interfaces get shut off after a while if they aren't "chatty." While my cluster is chatty by virtue of being a cluster, since it's all on the same ethernet switch, that doesn't really matter. While an actual fix would be to investigate interface shutdowns on non-chattiness, the temporary fix? Curl google.com every minute!&lt;/del&gt; &lt;a href="https://twitter.com/dvdmuckle/status/958019950001745922"&gt;https://twitter.com/dvdmuckle/status/958019950001745922&lt;/a&gt; Full Twitter thread of the issue solution! Turns out it wasn't exactly DHCP!&lt;/p&gt;

</description>
      <category>explainlikeimfive</category>
    </item>
    <item>
      <title>A Fun Little Bug</title>
      <dc:creator>David Muckle</dc:creator>
      <pubDate>Tue, 12 Sep 2017 03:20:15 +0000</pubDate>
      <link>https://dev.to/dvdmuckle/a-fun-little-bug</link>
      <guid>https://dev.to/dvdmuckle/a-fun-little-bug</guid>
      <description>&lt;p&gt;Today I ran into a fun little bug while debugging the shell I've been working on, while also using my VT420.&lt;/p&gt;

&lt;p&gt;My terminal has been weird for a while, and will sometimes fail to backspace on things such as password inputs. In this case, with my shell, it would print &lt;code&gt;^H&lt;/code&gt; instead of actually deleting a character.&lt;/p&gt;

&lt;p&gt;So, what happens if you run &lt;code&gt;ls -l foo ^H^H^H^H^H^H^H^H^H^H^H^H^H^H^H&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;You get the wonderful &lt;code&gt;: No such file or directory&lt;/code&gt;. But it should be listing the contents of &lt;code&gt;foo&lt;/code&gt;. What's going on?&lt;/p&gt;

&lt;p&gt;From this, we can infer some code in &lt;code&gt;ls&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%s: cannot access %s: No such file or directory&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see, because the &lt;code&gt;filename&lt;/code&gt; string has backspace characters in it, C will print it out, &lt;em&gt;including&lt;/em&gt; the backspace characters, thus deleting the printing about the command being run and the filename.&lt;/p&gt;

&lt;p&gt;Thankfully, this wasn't an issue with my shell, but rather my terminal. Changing firmware settings for the backspace key fixed things, including backspacing on password input.&lt;/p&gt;

</description>
      <category>shell</category>
      <category>bugs</category>
    </item>
    <item>
      <title>Learning Go for Fun and Profit</title>
      <dc:creator>David Muckle</dc:creator>
      <pubDate>Sun, 20 Aug 2017 21:58:27 +0000</pubDate>
      <link>https://dev.to/dvdmuckle/learning-go-for-fun-and-profit</link>
      <guid>https://dev.to/dvdmuckle/learning-go-for-fun-and-profit</guid>
      <description>&lt;p&gt;Okay, maybe no actual profit other than knowledge. But lots of fun!&lt;/p&gt;

&lt;p&gt;One of the perks of knowing C is being able to learn a lot of other languages without having to deviate much from the “C formula.”  It wasn’t for a while that a proper “sequel” to C came out. Go, or golang, was created by Ken Thompson, of UNIX and C fame, and some folks at Google. It’s basically C 2.0 with a package manager. Which is actually pretty awesome! Not only is it a simple language, using and getting libraries is a breeze. Once you get started, it’s incredibly easy to start building off of other Go libraries, or creating your own thing for others to use.&lt;/p&gt;

&lt;p&gt;So, how did I learn Go? Well, by virtue of knowing C, I already knew most basic things. Did that stop me from googling everything? Nope! For example, if you use a function from another library, say, from &lt;code&gt;fmt&lt;/code&gt;, you have to capitalize the function, so you would do &lt;code&gt;fmt.Sprintf&lt;/code&gt;. This is a little different compared to C, where it’s for the most part case insensitive. There are also multi line strings, some other odd formatting quirks, and neat tricks in terms of variable creation. My favorite thing about Go, and the first thing you learn, is short variable assignment and implicit typing. No more must you specify that 1 is an integer! Just say &lt;code&gt;x := 1&lt;/code&gt;. Of course there are cases where you might want to specify &lt;code&gt;x&lt;/code&gt; being, say, a float with a value of 1, or say that &lt;code&gt;y&lt;/code&gt; has a string value of &lt;code&gt;true&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;Most of my learning was done working on my friend’s project &lt;a href="https://github.com/davidscholberg/irkbot"&gt;Irkbot.&lt;/a&gt; Irkbot is a modular IRC bot written in Go using the go-ircevent library. Because it’s modular, it’s very easy to write new features. The first feature I did was the &lt;a href="https://github.com/dvdmuckle/irkbot/blob/master/lib/module/interject.go"&gt;@interject&lt;/a&gt;command, which simply prints out the popular Linux/GNU copypasta with whatever comes after the command, otherwise defaulting to Linux. It took me… Much longer than it should have to do something this simple, but I got it eventually. This also gave me some experience coding for someone else. Most work I do is either for myself or a grade, so I rarely get to change code based on feedback. It’s an interesting process, and it’s cool to see how other people format their code.&lt;/p&gt;

&lt;p&gt;The next feature I did was &lt;a href="https://github.com/dvdmuckle/irkbot/blob/master/lib/module/xkcd.go"&gt;@xkcd&lt;/a&gt;, a command that searches for pertinent xkcd comics based on the search term. To do this, I used &lt;a href="https://relevantxkcd.appspot.com"&gt;https://relevantxkcd.appspot.com&lt;/a&gt; as a backend, and the go-xkcd library to match comic numbers to comic names. This took a lot more work because I’d never done anything with HTTP requests like this before.&lt;/p&gt;

&lt;p&gt;The most recent feature I did was &lt;a href="https://github.com/dvdmuckle/irkbot/blob/master/lib/module/doom.go"&gt;@doom&lt;/a&gt;, which leverages the incredibly interesting &lt;a href="https://github.com/jeff-1amstudios/restful-doom"&gt;RESTful Doom&lt;/a&gt; to play Doom! This was a whole bunch of fun to do, and it was a blast when it started working. I also tweaked Irkbot’s configuration to be able to connect to IRC servers that require /PASS auth, so it can connect to Twitch chat. While this means one can play Doom over Twitch chat, the lag makes it almost impossible to actually accomplish anything. I’d love to test this with a lot more people at some point, so who knows.&lt;/p&gt;

&lt;p&gt;So far I’m really liking Go, and I haven’t found any issues with it yet. I have some plans in the future for extending Irkbot’s functionality, and to even create something completely new that will be used in conjunction with the ELK stack. Stay tuned on that! Or maybe keep your eye on my new &lt;a href="https://labs.dvdmuckle.xyz"&gt;lab&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The post &lt;a href="https://dvdmuckle.xyz/index.php/2017/08/20/learning-go-fun-profit/"&gt;Learning Go for Fun and Profit&lt;/a&gt; appeared first on &lt;a href="https://dvdmuckle.xyz"&gt;dvdmuckle&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>projects</category>
      <category>go</category>
    </item>
    <item>
      <title>One Year in FOSS</title>
      <dc:creator>David Muckle</dc:creator>
      <pubDate>Sun, 02 Apr 2017 21:40:51 +0000</pubDate>
      <link>https://dev.to/dvdmuckle/one-year-in-foss</link>
      <guid>https://dev.to/dvdmuckle/one-year-in-foss</guid>
      <description>&lt;p&gt;About a year ago, I became involved in the GalliumOS project. I had recently changed my major from film studies to computer science, the joke being “I switched to a different kind of script writing. A bit after that, I was approached by my professor with a job offer to be a systems administrator for the department. All of these things thrust me into the world of computer science and all that it encompasses.&lt;/p&gt;

&lt;p&gt;For the unaware, GalliumOS is a lightweight GNU/Linux distribution for Chromebooks. I’ve had a Chromebook since high school, and originally got it with the sole purpose of putting Linux on it. However, after the Chrubuntu project disappeared I couldn’t find a way to put Linux back on there, and most distros weren’t well equipped for the hardware. After my backup laptop, which I had been using for most work, died, I was happy to find GalliumOS. I quickly became a regular in their IRC channel, often helping people with mundane problems or installation.&lt;/p&gt;

&lt;p&gt;At one point, one of the devs asked if anyone was willing to moderate the forum on /r/GalliumOS. I volunteered, and was trusted enough to be accepted. I quickly became an operator on the IRC, and started contributing code to the project. My first contribution was replacing the stock Xubuntu install slideshow with a GalliumOS one. After that, an animated splash. Recently, updated icons.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;That took way too long. &lt;a href="https://t.co/b7RJN6o34D"&gt;pic.twitter.com/b7RJN6o34D&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;— David Muckle (&lt;a class="mentioned-user" href="https://dev.to/dvdmuckle"&gt;@dvdmuckle&lt;/a&gt;
) &lt;a href="https://twitter.com/dvdmuckle/status/743519821527138304"&gt;June 16, 2016&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The more I worked on this project, the more I began to appreciate the FOSS community. Things are easy to install, well documented, it’s easy to find help. Something doesn’t work? You can fix it. Find a bug? Report it. The more I take, the more I want to give back. Things are easy to use and just &lt;em&gt;work&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I’ve made it a point to move away from proprietary software and towards FOSS projects. Once I upgrade my computer, I intend to use Debian GNOME, as I feel it offers the same if not better “ecosystem of applications and features that Windows offers, without all the strange goings-on in the background. That, and Vim on Windows is terrible.&lt;/p&gt;

&lt;p&gt;One of the biggest thing I’ve learned is that if you want to help, there’s a place where you can help. Taking this plunge, I’ve learned more than I could have learned taking classes. The experience of working with a team of people,  all doing separate things to delivery one experience, is incredible, and something I intend to do for a long time. A simple “Thank You from a user feels better than any paycheck.&lt;/p&gt;

&lt;p&gt;I implore people to look into free and open source software. Use it. Contribute. Ask how you can help. Even if you know nothing about computers, there’s something you can do, and it’s one of the best learning experiences you can possibly have.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://dvdmuckle.xyz/index.php/2017/04/02/one-year-foss/"&gt;One Year in FOSS&lt;/a&gt; appeared first on &lt;a href="https://dvdmuckle.xyz"&gt;dvdmuckle&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>projects</category>
    </item>
    <item>
      <title>Hooking up a VT420 Terminal to a Raspberry Pi</title>
      <dc:creator>David Muckle</dc:creator>
      <pubDate>Tue, 25 Oct 2016 18:18:52 +0000</pubDate>
      <link>https://dev.to/dvdmuckle/hooking-up-a-vt420-terminal-to-a-raspberry-pi</link>
      <guid>https://dev.to/dvdmuckle/hooking-up-a-vt420-terminal-to-a-raspberry-pi</guid>
      <description>&lt;p&gt;A few months ago, I asked a friend to help me on a project to supply users with a public SSH “terminal that would take the form of a wall mounted laptop with a light Linux install and a script to prompt users for SSH credentials. Well, fast forward a few months to when I discovered the magic of physical serial terminals, and the fact they can still be used with modern machines. I also had a Raspberry Pi lying around that was not being used, so I put two and two together and set off on constructing a public SSH terminal using the Pi.&lt;/p&gt;

&lt;p&gt;My first challenge was trying to find a good terminal to go with. Most terminals, if not all, can use a standard DB9 serial connection, which can be boiled down to USB. I wrestled between two options, mainly an “all in one more traditional option, or something more resembling a modern PC.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which terminal should I purchase? Keep in mind the Fallout looking one is about $200 more than the other one. &lt;a href="https://t.co/y0FfivHgHt"&gt;pic.twitter.com/y0FfivHgHt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;– David Muckle (&lt;a class="mentioned-user" href="https://dev.to/dvdmuckle"&gt;@dvdmuckle&lt;/a&gt;
) &lt;a href="https://twitter.com/dvdmuckle/status/776480068671594496"&gt;September 15, 2016&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the end, I went for a VT420 as I like the amber monitor color, and I found instructions for hooking one up to a Pi. I also found I needed an adapter and a null modem cable in the DEC MMJ format. I picked up both from &lt;a href="http://www.pacificcable.com/"&gt;here&lt;/a&gt;.  The null modem cable resembles a telephone cable, while the adapter is something you have to solder yourself. Because my soldering skills aren’t what they used to be, I ended up burning my thumb and giving up on soldering the adapter, instead ordering an OEM one from &lt;a href="http://www.ebay.com/itm/DEC-H8571-J-DB9-Female-To-MMJ-Female-Adapter-9-PIN-SERIAL-TO-6-PIN-DEC423-MMJ-/262196697200?hash=item3d0c241870:g:8BEAAOSwo3pWct8P"&gt;here&lt;/a&gt;. Note the null modem cable is still required to connect the adapter to the terminal. After getting these parts, I was able to hook up the terminal to a PC with a serial port.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NYAHA! IT’S ALIVE! &lt;a href="https://t.co/tFwjnB8NaD"&gt;pic.twitter.com/tFwjnB8NaD&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;– David Muckle (&lt;a class="mentioned-user" href="https://dev.to/dvdmuckle"&gt;@dvdmuckle&lt;/a&gt;
) &lt;a href="https://twitter.com/dvdmuckle/status/782257576310288385"&gt;October 1, 2016&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, I had a choice. I could either use the GPIO pins on the Pi to get a serial port, or use a serial to USB adapter. I ordered both, to see if one would be better than the other. The end result was the USB adapter was much easier to configure, and more reliable, as many people &lt;a href="https://www.reddit.com/r/retrobattlestations/comments/55wnkl/question_serial_console_on_a_rpi_1b_wraspbian/"&gt;chimed in on /r/retrobattlestations&lt;/a&gt;. I ordered a USB adapter with a PL2303 chip. Avoid the CH340/HL340 at all costs, it will lead to corrupted text on the terminal, and is widely regarded as “eBay trash.”&lt;/p&gt;

&lt;p&gt;Here’s where things get… not as documented. Most documentation for getting a tty on a serial terminal use sysvinit, specifically the inittab file. Raspbian Jessie uses systemd, so it doesn’t have an inittab file. However, we can still get a serial terminal, if we make it a system service. Copy the skeleton file &lt;code&gt;/lib/systemd/system/serial-getty@.service&lt;/code&gt; to &lt;code&gt;/etc/systemd/system/&lt;/code&gt;, and rename it as you see fit. If you’re using a USB to serial adapter, rename it &lt;code&gt;serial-getty@ttyUSB0.service&lt;/code&gt;. It doesn’t really matter what it’s renamed to, but it helps for ease of use. Next, edit the &lt;code&gt;ExecStart=&lt;/code&gt; line in the skeleton file to work with your terminal. Mine looks like &lt;code&gt;ExecStart=-/sbin/agetty -a sshuser -p ttyUSB0 19200 vt420&lt;/code&gt;. You may need to put a -L in front of ttyUSB0. Note the baud rate is set to 19200. This has to be the same on your terminal side. I used the settings from &lt;a href="http://buzzdavidson.com/?p=425"&gt;here&lt;/a&gt; for configuring my VT420. Enable the systemd service with &lt;code&gt;sudo systemctl daemon-reload &amp;amp;&amp;amp; sudo systemctl start serial-getty@ttyUSB0.service&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Last, I copied the SSH script onto my machine and configured everything properly. If you’d like to use the script, it as well as instructions for it can be found &lt;a href="https://github.com/dvdmuckle/SSHThinClient"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So there you have it, a public SSH terminal. This will be sitting in the break room of the CS department on campus for the foreseeable future, or at least as long as I’m a student here at Clark University. Any questions can be directed towards either my Twitter or the comments below. Thanks again to ColtonDRG for help with the SSH script, without whom this project would probably have not happened.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://dvdmuckle.xyz/index.php/2016/10/25/hooking-up-a-vt420-terminal-to-a-raspberry-pi/"&gt;Hooking up a VT420 Terminal to a Raspberry Pi&lt;/a&gt; appeared first on &lt;a href="https://dvdmuckle.xyz"&gt;dvdmuckle&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>projects</category>
      <category>terminal</category>
      <category>retro</category>
    </item>
  </channel>
</rss>
