{"@attributes":{"version":"2.0"},"channel":{"title":"Kel's Blog","description":"Ramblings of a polygot developer that loves to build things.\n","link":"http:\/\/kelcecil.com\/","pubDate":"Sat, 01 Apr 2017 06:00:46 +0000","lastBuildDate":"Sat, 01 Apr 2017 06:00:46 +0000","generator":"Jekyll v3.4.3","item":[{"title":"HEY! There's OCaml in My Rust! Workshop Information","description":"<p>Hello Rust Belt Rust attendee, and thanks for your interest in my Rust Belt Rust workshop \u201cHEY! There\u2019s OCaml in My Rust!\u201d I appreciate the opportunity to introduce you to Rust, OCaml, or even possibly both! I hope you learn as much from the workshop as I did in preparation.<\/p>\n\n<p>The hands-on portion of the workshop will have attendees writing the same problem (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Binary_search_tree\">binary search tree<\/a>) in OCaml and Rust and sharing observations and ideas with other attendees. We\u2019ll step through one or two of the tree operations and invite attendees to write operations of their own or to explore and improve the ones we\u2019ve already written. You have two options for environments if you\u2019d like to participate: using online playgrounds or locally on your development machine (<em>highly recommended<\/em>).<\/p>\n\n<p>All of the Rust examples are written to run using the Rust playground hosted by <a href=\"http:\/\/play.integer32.com\/\">Integer32<\/a> or <a href=\"https:\/\/play.rust-lang.org\/\">The Rust Language website<\/a>. The OCaml examples are written to run on <a href=\"https:\/\/try.ocamlpro.com\/\">OCamlPro\u2019s Try OCaml app<\/a>.<\/p>\n\n<p>Here\u2019s a rundown of the software that should be installed and ready if you want to work locally:<\/p>\n\n<ul>\n  <li><a href=\"https:\/\/www.rust-lang.org\/en-US\/downloads.html\">Rust 1.12 or newer<\/a><\/li>\n  <li><a href=\"https:\/\/ocaml.org\/docs\/install.html\">OCaml 4.02.3 or later and OPAM<\/a><\/li>\n  <li>OUnit 2.0 (opam install ounit)<\/li>\n<\/ul>\n\n<p>You should have the following executables in your path when finished:<\/p>\n\n<ul>\n  <li>rustc<\/li>\n  <li>ocamlc<\/li>\n  <li>ocamlbuild<\/li>\n  <li>ocamlfind<\/li>\n<\/ul>\n\n<p>You\u2019re ready to go if you\u2019ve got those four programs installed.<\/p>\n\n<p>I look forward to meeting you at Rust Belt Rust! Feel free to reach out to me on <a href=\"https:\/\/twitter.com\/praisechaos\">Twitter<\/a> if you have questions or just want to say hi!<\/p>\n","pubDate":"Wed, 12 Oct 2016 23:05:00 +0000","link":"http:\/\/kelcecil.com\/rust\/2016\/10\/12\/rust-belt-rust-workshop-info.html","guid":"http:\/\/kelcecil.com\/rust\/2016\/10\/12\/rust-belt-rust-workshop-info.html","category":["rust","instructions","rust"]},{"title":"Querying Unix Sockets with curl","description":"<p>I recently found myself in a situation where I wanted to query the Docker socket to query their API for information, and I found myself wishing with every passing moment that I could just query a unix socket using a tool as simple and straight-forward as <em>curl<\/em>. Imagine my joy when I discovered that <em>curl<\/em> now has unix socket support in <em>curl<\/em> 7.40 and later. Discovering this new feature made my day, and I\u2019m thrilled to share this with you.<\/p>\n\n<p>Let\u2019s take a look at how this works by using <em>curl<\/em>\u2019s unix socket support to find out what images our local Docker daemon has available.<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-bash\" data-lang=\"bash\"><span class=\"c\"># curl -X METHOD --unix-socket \/path\/to\/socket.sock &lt;endpoint&gt;<\/span>\n<span class=\"gp\">kcecil@ubuntu:~$ <\/span>curl -X GET --unix-socket \/var\/run\/docker.sock http:\/images\/json\n<span class=\"o\">[{<\/span><span class=\"s2\">\"Id\"<\/span>:<span class=\"s2\">\"3a10494514dcef7fb1b48fb4ce3c25a941bfdb5b8dfd3a0275267fc1094e9782\"<\/span>,<span class=\"s2\">\"ParentId\"<\/span>:<span class=\"s2\">\"e34cf9c36b25be359613467859eb53af43787adeb35e902d68dc2a26d4b15538\"<\/span>,<span class=\"s2\">\"RepoTags\"<\/span>:[<span class=\"s2\">\"kelcecil\/chucksay:latest\"<\/span><span class=\"o\">]<\/span>,<span class=\"s2\">\"RepoDigests\"<\/span>:[],<span class=\"s2\">\"Created\"<\/span>:1433631743,<span class=\"s2\">\"Size\"<\/span>:0,<span class=\"s2\">\"VirtualSize\"<\/span>:486914149,<span class=\"s2\">\"Labels\"<\/span>:<span class=\"o\">{}}]<\/span><\/code><\/pre><\/figure>\n\n<p>That\u2019s pretty easy, huh? Simply use the \u2013unix-socket flag and make sure to throw <em>http:<\/em> before your endpoint (omitting the protocol in 7.46 DEV will result in a malformed url error). You can skip specifying the HTTP method (-X) if you\u2019re okay with <em>curl<\/em>\u2019s default of using the HTTP GET method.<\/p>\n\n<p>How much effort does using <em>curl<\/em> save? Here\u2019s an equivalent example using OpenBSD\u2019s <em>netcat<\/em> (also available on Ubuntu Server 15.04):<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-bash\" data-lang=\"bash\"><span class=\"gp\">kcecil@ubuntu:~$ <\/span><span class=\"nb\">echo<\/span> -e <span class=\"s2\">\"GET \/images\/json HTTP\/1.0<\/span><span class=\"se\">\\r\\n<\/span><span class=\"s2\">\"<\/span> | netcat -U \/var\/run\/docker.sock\nHTTP\/1.0 200 OK\nContent-Type: application\/json\nServer: Docker\/1.9.1 <span class=\"o\">(<\/span>linux<span class=\"o\">)<\/span>\nDate: Mon, 07 Dec 2015 21:44:20 GMT\nContent-Length: 277\n\n<span class=\"o\">[{<\/span><span class=\"s2\">\"Id\"<\/span>:<span class=\"s2\">\"3a10494514dcef7fb1b48fb4ce3c25a941bfdb5b8dfd3a0275267fc1094e9782\"<\/span>,<span class=\"s2\">\"ParentId\"<\/span>:<span class=\"s2\">\"e34cf9c36b25be359613467859eb53af43787adeb35e902d68dc2a26d4b15538\"<\/span>,<span class=\"s2\">\"RepoTags\"<\/span>:[<span class=\"s2\">\"kelcecil\/chucksay:latest\"<\/span><span class=\"o\">]<\/span>,<span class=\"s2\">\"RepoDigests\"<\/span>:[],<span class=\"s2\">\"Created\"<\/span>:1433631743,<span class=\"s2\">\"Size\"<\/span>:0,<span class=\"s2\">\"VirtualSize\"<\/span>:486914149,<span class=\"s2\">\"Labels\"<\/span>:<span class=\"o\">{}}]<\/span><\/code><\/pre><\/figure>\n\n<p>How useful is using <em>curl<\/em> over <em>netcat<\/em>? Using <em>curl<\/em> can potentially provide benefits in scripting and ease of use, but anyone who already has the muscle memory to hammer out something familiar to the <em>netcat<\/em> line above might not be as easily persuaded by the convenience. <em>curl<\/em> 7.40 may also not be available in some software repositories, so knowledge of using <em>netcat<\/em> still may be useful if a newer version of <em>curl<\/em> isn\u2019t available.<\/p>\n\n<p>You\u2019ll be ready to work with a unix socket next time you find yourself in a similar position. Go forth and <em>curl<\/em>!<\/p>\n","pubDate":"Mon, 07 Dec 2015 20:11:00 +0000","link":"http:\/\/kelcecil.com\/curl\/2015\/12\/07\/query-unix-socket-with-curl.html","guid":"http:\/\/kelcecil.com\/curl\/2015\/12\/07\/query-unix-socket-with-curl.html","category":["curl","unix-sockets","netcat","curl"]},{"title":"Keeping Your Github Fork Updated","description":"<p>Tonight was a rainy, cold night in my town, so I spent the evening trying to get my four pull requests in for <a href=\"https:\/\/hacktoberfest.digitalocean.com\/\">Digital Ocean\u2019s Hackoberfest<\/a>. I found myself updating an old fork on <a href=\"https:\/\/github.com\/kelcecil\">my Github page<\/a> and reflecting on the questions I had when starting with Git and Github. How to update my personal fork on Github from the original repository was one of my first tasks I learned, and I thought I\u2019d take the opportunity to pass the knowledge along in the spirit of Hackoberfest.\n<!--more--><\/p>\n\n<p>I have a <a href=\"https:\/\/github.com\/kelcecil\/kubernetes\">fork of Kubernetes<\/a> in my Github account for preparing pull requests. I can clone my repository to my development workstation using <em>git clone<\/em>:<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-bash\" data-lang=\"bash\"><span class=\"gp\">&gt; <\/span>git clone git@github.com:kelcecil\/kubernetes.git\nCloning into <span class=\"s1\">'kubernetes'<\/span>...\nremote: Counting objects: 162966, <span class=\"k\">done<\/span>.\nremote: Compressing objects: 100% <span class=\"o\">(<\/span>6\/6<span class=\"o\">)<\/span>, <span class=\"k\">done<\/span>.\nremote: Total 162966 <span class=\"o\">(<\/span>delta 0<span class=\"o\">)<\/span>, reused 0 <span class=\"o\">(<\/span>delta 0<span class=\"o\">)<\/span>, pack-reused 162960\nReceiving objects: 100% <span class=\"o\">(<\/span>162966\/162966<span class=\"o\">)<\/span>, 124.80 MiB | 8.79 MiB\/s, <span class=\"k\">done<\/span>.\nResolving deltas: 100% <span class=\"o\">(<\/span>106653\/106653<span class=\"o\">)<\/span>, <span class=\"k\">done<\/span>.\nChecking connectivity... <span class=\"k\">done<\/span>.<\/code><\/pre><\/figure>\n\n<p>The URI used in the <em>git clone<\/em> command is stored as a remote named <em>origin<\/em>. We can verify this very easily using <em>git remote<\/em>:<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-bash\" data-lang=\"bash\"><span class=\"gp\">&gt; <\/span>git remote -v                                                                   \norigin  git@github.com:kelcecil\/kubernetes.git <span class=\"o\">(<\/span>fetch<span class=\"o\">)<\/span>\norigin  git@github.com:kelcecil\/kubernetes.git <span class=\"o\">(<\/span>push<span class=\"o\">)<\/span><\/code><\/pre><\/figure>\n\n<p>This remote named origin is the repository location we are referring to when we perform <em>git push origin master<\/em> or <em>git pull origin master<\/em>. <em>origin<\/em> is only one possible location, and we can add other remote repositories such as the upstream repository that we\u2019d like to pull data from. Let\u2019s add the main Kubernetes repository as a remote named <em>upstream<\/em> using <em>git remote add<\/em>.<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-bash\" data-lang=\"bash\"><span class=\"gp\">&gt; <\/span>git remote add upstream git@github.com:kubernetes\/kubernetes.git\n<span class=\"gp\">&gt; <\/span>git remote -v\norigin  git@github.com:kelcecil\/kubernetes.git <span class=\"o\">(<\/span>fetch<span class=\"o\">)<\/span>\norigin  git@github.com:kelcecil\/kubernetes.git <span class=\"o\">(<\/span>push<span class=\"o\">)<\/span>\nupstream        git@github.com:kubernetes\/kubernetes.git <span class=\"o\">(<\/span>fetch<span class=\"o\">)<\/span>\nupstream        git@github.com:kubernetes\/kubernetes.git <span class=\"o\">(<\/span>push<span class=\"o\">)<\/span><\/code><\/pre><\/figure>\n\n<p>We can now easily update our code from the upstream Kubernetes repository with a simple <em>git pull<\/em>. You can then push your repository to origin to update your forked repository.<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-bash\" data-lang=\"bash\"><span class=\"gp\">&gt; <\/span>git pull upstream master\n...\n<span class=\"gp\">&gt; <\/span>git push origin master\n...<\/code><\/pre><\/figure>\n\n<p>Excellent work! Our forked repository is now up to date with the upstream repository, and we\u2019re ready to hack on our favorite project!<\/p>\n","pubDate":"Wed, 28 Oct 2015 02:36:00 +0000","link":"http:\/\/kelcecil.com\/git\/2015\/10\/28\/updating-repo-from-upstream.html","guid":"http:\/\/kelcecil.com\/git\/2015\/10\/28\/updating-repo-from-upstream.html","category":["git","github","open source","git"]},{"title":"Cross Compiling in Go 1.5","description":"<p>Are you a developer that develops on one operating system and deploys to another? You might be an open source developer that wants to generate binaries for combinations of operating systems and platforms? One of the coolest features of Go 1.5 is how easy cross-compiling your applications for other architectures and operating systems can be, and I\u2019m going to show you how in this post.\n<!--more--><\/p>\n\n<p>Why might we need to cross-compile our code? One of my favorite aspects of Golang are the  binaries that are produced during a build. Gone are the days of having to install a runtime and dependencies on production boxes to execute that incredibly helpful script. Go\u2019s static binaries include everything you\u2019ll need to run your app in a single easy-to-transfer executable. <a href=\"http:\/\/www.youtube.com\/watch?v=wyRbHhHFZh8\">This is a fantastic asset for system administrators,<\/a> but this convenience comes with a minor concern. Using low-level binaries means that we\u2019ll need binaries prepared for specific processor architecture and platform combinations. This may sound like a hassle, but read on to see how Go 1.5 makes this task trivial!<\/p>\n\n<p>Let\u2019s take this incredibly simple Go application and pretend this is a slick tool for system administrators:<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-go\" data-lang=\"go\"><span class=\"k\">package<\/span><span class=\"x\"> <\/span><span class=\"n\">main<\/span><span class=\"x\">\n\n<\/span><span class=\"k\">import<\/span><span class=\"x\"> <\/span><span class=\"p\">(<\/span><span class=\"x\">\n        <\/span><span class=\"s\">\"fmt\"<\/span><span class=\"x\">\n        <\/span><span class=\"s\">\"time\"<\/span><span class=\"x\">\n<\/span><span class=\"p\">)<\/span><span class=\"x\">\n\n<\/span><span class=\"k\">func<\/span><span class=\"x\"> <\/span><span class=\"n\">main<\/span><span class=\"p\">()<\/span><span class=\"x\"> <\/span><span class=\"p\">{<\/span><span class=\"x\">\n        <\/span><span class=\"k\">for<\/span><span class=\"x\"> <\/span><span class=\"p\">{<\/span><span class=\"x\">\n                <\/span><span class=\"n\">fmt<\/span><span class=\"o\">.<\/span><span class=\"n\">Println<\/span><span class=\"p\">(<\/span><span class=\"s\">\"Hello!\"<\/span><span class=\"p\">)<\/span><span class=\"x\">\n                <\/span><span class=\"n\">time<\/span><span class=\"o\">.<\/span><span class=\"n\">Sleep<\/span><span class=\"p\">(<\/span><span class=\"n\">time<\/span><span class=\"o\">.<\/span><span class=\"n\">Second<\/span><span class=\"p\">)<\/span><span class=\"x\">\n        <\/span><span class=\"p\">}<\/span><span class=\"x\">\n<\/span><span class=\"p\">}<\/span><\/code><\/pre><\/figure>\n\n<p>What an awesome, feature-rich tool! Let\u2019s build our tool using <em>go build<\/em>:<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-bash\" data-lang=\"bash\">go build -o hello main.go<\/code><\/pre><\/figure>\n\n<p><em>go build<\/em> uses the host operating system and processor architecture by default. We can verify the format of the produced binary using the <em>file<\/em> utility and see this binary was prepared for a x86-64 (64-bit, Intel-based) processor running on Mac OS (which uses the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Mach-O\">Mach-O file format<\/a>):<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-bash\" data-lang=\"bash\"><span class=\"gp\">&gt; <\/span>file hello\nhello: Mach-O 64-bit executable x86_64<\/code><\/pre><\/figure>\n\n<p>We now have this excellent utility that works on a x86-64, Mac OS machine, but we need to compile our application for x86-64, Linux-based machines. You can easily set the target operating system and processor architecture using the environment variables GOOS and GOARCH respectively. Building for a Linux system using an x86-64 processor (commonly also referred to as an amd64 processor) is as simple as running this one-liner:<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-bash\" data-lang=\"bash\"><span class=\"nv\">GOOS<\/span><span class=\"o\">=<\/span>linux <span class=\"nv\">GOARCH<\/span><span class=\"o\">=<\/span>amd64 go build -o hello main.go<\/code><\/pre><\/figure>\n\n<p>The <em>file<\/em> utility tells us that our binary has been prepared using the ELF executable format and ready for action on a x86-64 Linux system.<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-bash\" data-lang=\"bash\"><span class=\"gp\">&gt; <\/span>file hello\nhello: ELF 64-bit LSB executable, x86-64, version 1 <span class=\"o\">(<\/span>SYSV<span class=\"o\">)<\/span>, statically linked, not stripped<\/code><\/pre><\/figure>\n\n<p>Easy, huh? Cross-compiling in Go 1.5 is that simple!<\/p>\n\n<p>I can hear your next question from the other side of the internet. What architectures and operating systems does Go 1.5 support? Go currently enjoys operating system support for Windows, OS X, Linux, plenty of BSD variants, and <a href=\"https:\/\/en.wikipedia.org\/wiki\/Plan_9_from_Bell_Labs\">Plan 9<\/a> among others. Supported architectures includes x86, x86-64 (amd64), 32 and 64-bit arm processors, PowerPC, and others! A list of valid operating system and processor architecture combinations are available in <a href=\"https:\/\/golang.org\/doc\/install\/source\">the Go documentation<\/a>.<\/p>\n\n<p>We can also take a peak inside the source for <a href=\"https:\/\/github.com\/golang\/go\/blob\/master\/src\/cmd\/dist\/build.go\"><em>go build<\/em><\/a> and see what <em>go build<\/em> will accept.<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-go\" data-lang=\"go\"><span class=\"c\">\/\/ The known architectures.<\/span><span class=\"x\">\n<\/span><span class=\"k\">var<\/span><span class=\"x\"> <\/span><span class=\"n\">okgoarch<\/span><span class=\"x\"> <\/span><span class=\"o\">=<\/span><span class=\"x\"> <\/span><span class=\"p\">[]<\/span><span class=\"kt\">string<\/span><span class=\"p\">{<\/span><span class=\"x\">\n\t<\/span><span class=\"s\">\"386\"<\/span><span class=\"p\">,<\/span><span class=\"x\">\n\t<\/span><span class=\"s\">\"amd64\"<\/span><span class=\"p\">,<\/span><span class=\"x\">\n\t<\/span><span class=\"s\">\"amd64p32\"<\/span><span class=\"p\">,<\/span><span class=\"x\">\n\t<\/span><span class=\"s\">\"arm\"<\/span><span class=\"p\">,<\/span><span class=\"x\">\n\t<\/span><span class=\"s\">\"arm64\"<\/span><span class=\"p\">,<\/span><span class=\"x\">\n\t<\/span><span class=\"s\">\"ppc64\"<\/span><span class=\"p\">,<\/span><span class=\"x\">\n\t<\/span><span class=\"s\">\"ppc64le\"<\/span><span class=\"p\">,<\/span><span class=\"x\">\n<\/span><span class=\"p\">}<\/span><span class=\"x\">\n\n<\/span><span class=\"c\">\/\/ The known operating systems.<\/span><span class=\"x\">\n<\/span><span class=\"k\">var<\/span><span class=\"x\"> <\/span><span class=\"n\">okgoos<\/span><span class=\"x\"> <\/span><span class=\"o\">=<\/span><span class=\"x\"> <\/span><span class=\"p\">[]<\/span><span class=\"kt\">string<\/span><span class=\"p\">{<\/span><span class=\"x\">\n\t<\/span><span class=\"s\">\"darwin\"<\/span><span class=\"p\">,<\/span><span class=\"x\">\n\t<\/span><span class=\"s\">\"dragonfly\"<\/span><span class=\"p\">,<\/span><span class=\"x\">\n\t<\/span><span class=\"s\">\"linux\"<\/span><span class=\"p\">,<\/span><span class=\"x\">\n\t<\/span><span class=\"s\">\"android\"<\/span><span class=\"p\">,<\/span><span class=\"x\">\n\t<\/span><span class=\"s\">\"solaris\"<\/span><span class=\"p\">,<\/span><span class=\"x\">\n\t<\/span><span class=\"s\">\"freebsd\"<\/span><span class=\"p\">,<\/span><span class=\"x\">\n\t<\/span><span class=\"s\">\"nacl\"<\/span><span class=\"p\">,<\/span><span class=\"x\">\n\t<\/span><span class=\"s\">\"netbsd\"<\/span><span class=\"p\">,<\/span><span class=\"x\">\n\t<\/span><span class=\"s\">\"openbsd\"<\/span><span class=\"p\">,<\/span><span class=\"x\">\n\t<\/span><span class=\"s\">\"plan9\"<\/span><span class=\"p\">,<\/span><span class=\"x\">\n\t<\/span><span class=\"s\">\"windows\"<\/span><span class=\"p\">,<\/span><span class=\"x\">\n<\/span><span class=\"p\">}<\/span><\/code><\/pre><\/figure>\n\n<p>I highly recommend using the combinations in <a href=\"https:\/\/golang.org\/doc\/install\/source\">the Go documentation<\/a> for applications that require stability, but peeking into the source provides a glimpse into what <a href=\"https:\/\/github.com\/golang\/mobile\">the future might bring<\/a>.<\/p>\n\n<p>You\u2019re now prepared to cross-compile some of your Go tools to share with friends using other architectures and environments! Try experimenting with building binaries for different platforms, and be sure to share what you learn!<\/p>\n","pubDate":"Sat, 24 Oct 2015 03:52:00 +0000","link":"http:\/\/kelcecil.com\/golang\/2015\/10\/24\/cross-compiling-in-go-1.5.html","guid":"http:\/\/kelcecil.com\/golang\/2015\/10\/24\/cross-compiling-in-go-1.5.html","category":["golang","cross-compile","golang"]},{"title":"Don't Sweat What You Can't Control","description":"<p>I was honored to be part of Ohio Linuxfest\u2019s 2015 schedule this year. My presentation agenda was introducing Kubernetes resources and processes such as the api server, kubelet and others using slides. I followed with a live demonstration where I deployed a container with my blog to a Kubernetes cluster.<\/p>\n\n<p>The thought of doing a demonstration was somewhat terrifying to me. A speaker\u2019s primary goal is to present an argument through a convincing story, and I was feeling nervous about presentation. What if I stumbled when discussing something? What if I said something that didn\u2019t make any sense? What do I do if I have an attendee that really wanted to heckle me? I imagined doomsday-like scenarios where my demonstration crashed and caused a room full of people to decide never to give Kubernetes a shot. Perhaps my presentation would be so disastrous that these fine listeners might give up computing entirely and relocate to the Himalayas to reconnect with nature? This all may seem a bit ridiculous, but that\u2019s just how irrational fear can be.<\/p>\n\n<p>My Ohio Linuxfest \u201815 presentation started out strong, but my demo suffered from a slight problem. I submitted a replication controller using kubectl that should have used a cached Docker image on my nodes to create the pods. Kubelet on the nodes unexpectedly tried to query my Docker repository. The conference wifi was unreliable, and I quickly found my request to the repository 404\u2019d. I did my best to make a joke out of this unfortunate turn of events, but I was beginning to enter a panic mode. I\u2019d prepared a plan B for my slides, but I really didn\u2019t want to find myself faced with using my boring backup slides for my talk. My audience was digging the demonstration, and I would be heartbroken for my talk to end like that.<\/p>\n\n<p>A member of the audience named Bill stepped up and offers their personal wifi access point for my use. I was able to connect to his wifi, get the images I needed, and finish the presentation. The audience loved the presentation, and I received tons of positive feedback.<\/p>\n\n<p>I reflected on this experience for a while, and I came to a few conclusions. Demonstrations aren\u2019t always going to go your way, but handling the unexpected is just as important as performing what you\u2019ve rehearsed. A presenter\u2019s attitude when dealing with  unexpected problems can show the audience that problems can be easily dealt with. Unexpected issues also provide members of your audience and the community to step up and be a part of your presentation.<\/p>\n\n<p>What the overall lesson here? Don\u2019t sweat what you can\u2019t control. The unexpected problems can add to your presentation if you approach them with the right attitude.<\/p>\n","pubDate":"Sun, 04 Oct 2015 04:31:06 +0000","link":"http:\/\/kelcecil.com\/speaking\/2015\/10\/04\/dont-sweat-what-you-cant-control.html","guid":"http:\/\/kelcecil.com\/speaking\/2015\/10\/04\/dont-sweat-what-you-cant-control.html","category":["ohiolinux","encouragement","kubernetes","speaking"]},{"title":"Using go generate in Go 1.4","description":"<p>I\u2019m finding that my love for code that generates code grows as I get further in my life as a developer. Every individual method or function is one more item that I\u2019m responsible for, and I\u2019m a huge fan of reducing that responsibility. I\u2019d love to share a way to accomplish this in Golang, and I\u2019ll point to a small project on Github where I give this a go.<\/p>\n\n<!--more-->\n\n<p>Go 1.4 introduced the generate tool in order to allow directives in Go source to call command line applications to generate code. Code generation seems to be a pretty popular idea in the Go community, and this new tool carries the idea a little further. The Golang blog (and several other places) use <a href=\"http:\/\/blog.golang.org\/generate\">generate to implement a grammar<\/a> like so:<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-go\" data-lang=\"go\"><span class=\"c\">\/\/go:generate go tool yacc -o gopher.go -p parser gopher.y<\/span><\/code><\/pre><\/figure>\n\n<p>This seems like a great use of the generate tool, but I for one don\u2019t implement grammars on daily basis. The generate tool seemed cool, but I tucked the idea away in my mind until a few nights ago.<\/p>\n\n<p>I was implementing calls to the GamesDB web service for a Go app I was writing when I noticed that all of my functions looked almost identical to each other. The functions were identical with the exception of the function names, the first return value (with the second always being of type error), and the endpoint of the API call. I didn\u2019t want to copy and paste the code as that made for separate code for each call that had to be maintained. I wanted to be able to make a change once and generate my functions from that.<\/p>\n\n<p>I started by writing a command line app in Go that accepted the above parameters and additionally a file name to output the source. I began with creating a template for the function and file I wanted to generate:<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-go\" data-lang=\"go\"><span class=\"k\">package<\/span><span class=\"x\"> <\/span><span class=\"n\">thegamesdb<\/span><span class=\"x\">\n\n<\/span><span class=\"k\">import<\/span><span class=\"x\"> <\/span><span class=\"p\">(<\/span><span class=\"x\">\n        <\/span><span class=\"s\">\"encoding\/xml\"<\/span><span class=\"x\">\n        <\/span><span class=\"s\">\"net\/http\"<\/span><span class=\"x\">\n<\/span><span class=\"p\">)<\/span><span class=\"x\">\n\n<\/span><span class=\"k\">func<\/span><span class=\"x\"> <\/span><span class=\"p\">{{<\/span><span class=\"o\">.<\/span><span class=\"n\">MethodName<\/span><span class=\"p\">}}(<\/span><span class=\"n\">parameters<\/span><span class=\"x\"> <\/span><span class=\"k\">map<\/span><span class=\"p\">[<\/span><span class=\"kt\">string<\/span><span class=\"p\">]<\/span><span class=\"kt\">string<\/span><span class=\"p\">)<\/span><span class=\"x\"> <\/span><span class=\"p\">(<\/span><span class=\"o\">*<\/span><span class=\"p\">{{<\/span><span class=\"o\">.<\/span><span class=\"n\">OutputType<\/span><span class=\"p\">}},<\/span><span class=\"x\"> <\/span><span class=\"kt\">error<\/span><span class=\"p\">)<\/span><span class=\"x\"> <\/span><span class=\"p\">{<\/span><span class=\"x\">\n        <\/span><span class=\"k\">var<\/span><span class=\"x\"> <\/span><span class=\"n\">output<\/span><span class=\"x\"> <\/span><span class=\"p\">{{<\/span><span class=\"o\">.<\/span><span class=\"n\">OutputType<\/span><span class=\"p\">}}<\/span><span class=\"x\">\n        <\/span><span class=\"n\">endpoint<\/span><span class=\"x\"> <\/span><span class=\"o\">:=<\/span><span class=\"x\"> <\/span><span class=\"s\">\"{{.ApiEndpoint}}?\"<\/span><span class=\"x\"> <\/span><span class=\"o\">+<\/span><span class=\"x\"> <\/span><span class=\"n\">ConvertMapIntoGetParams<\/span><span class=\"p\">(<\/span><span class=\"n\">parameters<\/span><span class=\"p\">)<\/span><span class=\"x\">\n        <\/span><span class=\"n\">resp<\/span><span class=\"p\">,<\/span><span class=\"x\"> <\/span><span class=\"n\">err<\/span><span class=\"x\"> <\/span><span class=\"o\">:=<\/span><span class=\"x\"> <\/span><span class=\"n\">http<\/span><span class=\"o\">.<\/span><span class=\"n\">Get<\/span><span class=\"p\">(<\/span><span class=\"n\">apiEndpoint<\/span><span class=\"x\"> <\/span><span class=\"o\">+<\/span><span class=\"x\"> <\/span><span class=\"n\">endpoint<\/span><span class=\"p\">)<\/span><span class=\"x\">\n        <\/span><span class=\"k\">if<\/span><span class=\"x\"> <\/span><span class=\"n\">err<\/span><span class=\"x\"> <\/span><span class=\"o\">!=<\/span><span class=\"x\"> <\/span><span class=\"no\">nil<\/span><span class=\"x\"> <\/span><span class=\"p\">{<\/span><span class=\"x\">\n                <\/span><span class=\"k\">return<\/span><span class=\"x\"> <\/span><span class=\"no\">nil<\/span><span class=\"p\">,<\/span><span class=\"x\"> <\/span><span class=\"n\">err<\/span><span class=\"x\">\n        <\/span><span class=\"p\">}<\/span><span class=\"x\">\n\n        <\/span><span class=\"k\">defer<\/span><span class=\"x\"> <\/span><span class=\"n\">resp<\/span><span class=\"o\">.<\/span><span class=\"n\">Body<\/span><span class=\"o\">.<\/span><span class=\"n\">Close<\/span><span class=\"p\">()<\/span><span class=\"x\">\n        <\/span><span class=\"n\">decoder<\/span><span class=\"x\"> <\/span><span class=\"o\">:=<\/span><span class=\"x\"> <\/span><span class=\"n\">xml<\/span><span class=\"o\">.<\/span><span class=\"n\">NewDecoder<\/span><span class=\"p\">(<\/span><span class=\"n\">resp<\/span><span class=\"o\">.<\/span><span class=\"n\">Body<\/span><span class=\"p\">)<\/span><span class=\"x\">\n        <\/span><span class=\"n\">decoder<\/span><span class=\"o\">.<\/span><span class=\"n\">Decode<\/span><span class=\"p\">(<\/span><span class=\"o\">&amp;<\/span><span class=\"n\">output<\/span><span class=\"p\">)<\/span><span class=\"x\">\n        <\/span><span class=\"k\">return<\/span><span class=\"x\"> <\/span><span class=\"o\">&amp;<\/span><span class=\"n\">output<\/span><span class=\"p\">,<\/span><span class=\"x\"> <\/span><span class=\"no\">nil<\/span><span class=\"x\">\n<\/span><span class=\"p\">}<\/span><\/code><\/pre><\/figure>\n\n<p>Notice that the parameters passed in are represented in the template by the double handlebars (). These parameters are represented by a struct I constructed to hold these options to call them into the template.<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-go\" data-lang=\"go\"><span class=\"k\">type<\/span><span class=\"x\"> <\/span><span class=\"n\">Options<\/span><span class=\"x\"> <\/span><span class=\"k\">struct<\/span><span class=\"x\"> <\/span><span class=\"p\">{<\/span><span class=\"x\">\n        <\/span><span class=\"n\">Output<\/span><span class=\"x\">      <\/span><span class=\"kt\">string<\/span><span class=\"x\">\n        <\/span><span class=\"n\">MethodName<\/span><span class=\"x\">  <\/span><span class=\"kt\">string<\/span><span class=\"x\">\n        <\/span><span class=\"n\">ApiEndpoint<\/span><span class=\"x\"> <\/span><span class=\"kt\">string<\/span><span class=\"x\">\n        <\/span><span class=\"n\">OutputType<\/span><span class=\"x\">  <\/span><span class=\"kt\">string<\/span><span class=\"x\">\n<\/span><span class=\"p\">}<\/span><\/code><\/pre><\/figure>\n\n<p>Generating the source is as simple as parsing the template and executing with a Writer and my options struct.<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-go\" data-lang=\"go\"><span class=\"n\">tmpl<\/span><span class=\"p\">,<\/span><span class=\"x\"> <\/span><span class=\"n\">err<\/span><span class=\"x\"> <\/span><span class=\"o\">:=<\/span><span class=\"x\"> <\/span><span class=\"n\">template<\/span><span class=\"o\">.<\/span><span class=\"n\">New<\/span><span class=\"p\">(<\/span><span class=\"s\">\"method\"<\/span><span class=\"p\">)<\/span><span class=\"o\">.<\/span><span class=\"n\">Parse<\/span><span class=\"p\">(<\/span><span class=\"n\">methodTemplate<\/span><span class=\"p\">)<\/span><span class=\"x\">\n<\/span><span class=\"n\">err<\/span><span class=\"x\"> <\/span><span class=\"o\">=<\/span><span class=\"x\"> <\/span><span class=\"n\">tmpl<\/span><span class=\"o\">.<\/span><span class=\"n\">Execute<\/span><span class=\"p\">(<\/span><span class=\"n\">writer<\/span><span class=\"p\">,<\/span><span class=\"x\"> <\/span><span class=\"n\">options<\/span><span class=\"p\">)<\/span><\/code><\/pre><\/figure>\n\n<p>The full source to this is available at [https:\/\/github.com\/kelcecil\/go-gamesdb\/blob\/master\/generategamesdb\/generate_gamesdb_call.go]. If you\u2019re not familiar with Go\u2019s <a href=\"http:\/\/golang.org\/pkg\/text\/template\/\">text\/template<\/a>, then I highly recommend giving it a look as well.<\/p>\n\n<p>All that remains is to add directives to the source to generate the functions when executing go generate like so:<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-go\" data-lang=\"go\"><span class=\"c\">\/\/go:generate generategamesdb -output get_art.go -method GetArt -type GetArtResponse -endpoint GetArt.php<\/span><\/code><\/pre><\/figure>\n\n<p>My executable is called generategamesdb, but you can replace this with any executable in your <em>PATH<\/em> (make sure that <em>${GOPATH}\/bin<\/em> is in your <em>PATH<\/em> if you\u2019re interesting in using a Go command line app like I am.) Running go generate after adding my generate directive provides beautiful, generated functions like so:<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-go\" data-lang=\"go\"><span class=\"k\">func<\/span><span class=\"x\"> <\/span><span class=\"n\">GetArt<\/span><span class=\"p\">(<\/span><span class=\"n\">parameters<\/span><span class=\"x\"> <\/span><span class=\"k\">map<\/span><span class=\"p\">[<\/span><span class=\"kt\">string<\/span><span class=\"p\">]<\/span><span class=\"kt\">string<\/span><span class=\"p\">)<\/span><span class=\"x\"> <\/span><span class=\"p\">(<\/span><span class=\"o\">*<\/span><span class=\"n\">GetArtResponse<\/span><span class=\"p\">,<\/span><span class=\"x\"> <\/span><span class=\"kt\">error<\/span><span class=\"p\">)<\/span><span class=\"x\"> <\/span><span class=\"p\">{<\/span><span class=\"x\">\n        <\/span><span class=\"k\">var<\/span><span class=\"x\"> <\/span><span class=\"n\">output<\/span><span class=\"x\"> <\/span><span class=\"n\">GetArtResponse<\/span><span class=\"x\">\n        <\/span><span class=\"n\">endpoint<\/span><span class=\"x\"> <\/span><span class=\"o\">:=<\/span><span class=\"x\"> <\/span><span class=\"s\">\"GetArt.php?\"<\/span><span class=\"x\"> <\/span><span class=\"o\">+<\/span><span class=\"x\"> <\/span><span class=\"n\">ConvertMapIntoGetParams<\/span><span class=\"p\">(<\/span><span class=\"n\">parameters<\/span><span class=\"p\">)<\/span><span class=\"x\">\n        <\/span><span class=\"n\">resp<\/span><span class=\"p\">,<\/span><span class=\"x\"> <\/span><span class=\"n\">err<\/span><span class=\"x\"> <\/span><span class=\"o\">:=<\/span><span class=\"x\"> <\/span><span class=\"n\">http<\/span><span class=\"o\">.<\/span><span class=\"n\">Get<\/span><span class=\"p\">(<\/span><span class=\"n\">apiEndpoint<\/span><span class=\"x\"> <\/span><span class=\"o\">+<\/span><span class=\"x\"> <\/span><span class=\"n\">endpoint<\/span><span class=\"p\">)<\/span><span class=\"x\">\n        <\/span><span class=\"k\">if<\/span><span class=\"x\"> <\/span><span class=\"n\">err<\/span><span class=\"x\"> <\/span><span class=\"o\">!=<\/span><span class=\"x\"> <\/span><span class=\"no\">nil<\/span><span class=\"x\"> <\/span><span class=\"p\">{<\/span><span class=\"x\">\n                <\/span><span class=\"k\">return<\/span><span class=\"x\"> <\/span><span class=\"no\">nil<\/span><span class=\"p\">,<\/span><span class=\"x\"> <\/span><span class=\"n\">err<\/span><span class=\"x\">\n        <\/span><span class=\"p\">}<\/span><span class=\"x\">\n\n        <\/span><span class=\"k\">defer<\/span><span class=\"x\"> <\/span><span class=\"n\">resp<\/span><span class=\"o\">.<\/span><span class=\"n\">Body<\/span><span class=\"o\">.<\/span><span class=\"n\">Close<\/span><span class=\"p\">()<\/span><span class=\"x\">\n        <\/span><span class=\"n\">decoder<\/span><span class=\"x\"> <\/span><span class=\"o\">:=<\/span><span class=\"x\"> <\/span><span class=\"n\">xml<\/span><span class=\"o\">.<\/span><span class=\"n\">NewDecoder<\/span><span class=\"p\">(<\/span><span class=\"n\">resp<\/span><span class=\"o\">.<\/span><span class=\"n\">Body<\/span><span class=\"p\">)<\/span><span class=\"x\">\n        <\/span><span class=\"n\">decoder<\/span><span class=\"o\">.<\/span><span class=\"n\">Decode<\/span><span class=\"p\">(<\/span><span class=\"o\">&amp;<\/span><span class=\"n\">output<\/span><span class=\"p\">)<\/span><span class=\"x\">\n        <\/span><span class=\"k\">return<\/span><span class=\"x\"> <\/span><span class=\"o\">&amp;<\/span><span class=\"n\">output<\/span><span class=\"p\">,<\/span><span class=\"x\"> <\/span><span class=\"no\">nil<\/span><span class=\"x\">\n<\/span><span class=\"p\">}<\/span><\/code><\/pre><\/figure>\n\n<p>If you\u2019d like to check out a working example of this flow, feel free to view my repository for go-gamesdb at [https:\/\/github.com\/kelcecil\/go-gamesdb\/]. Feel free to pull it down, play with it, write an app with it, and learn from it. Pull requests are always welcome if you see anything you\u2019d like to add.<\/p>\n\n<p>I hope you\u2019ll give go generate a try and share your experiences! I can\u2019t wait to see what other uses we can come up with as we begin to use the tool.<\/p>\n","pubDate":"Fri, 09 Jan 2015 02:24:12 +0000","link":"http:\/\/kelcecil.com\/golang\/2015\/01\/09\/using-go-generate-in-go-1-dot-4.html","guid":"http:\/\/kelcecil.com\/golang\/2015\/01\/09\/using-go-generate-in-go-1-dot-4.html","category":["golang","github","gamesdb","golang"]},{"title":"Anonymous Structs in Go","description":"<p>Did you know you can use anonymous structs in Go? A co-worker and I discovered this when trying to figure out an easy way to format data to send to the json Marshal method in the standard library. It\u2019s incredibly easy to do and easier than using a blank interface!<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-go\" data-lang=\"go\"><span class=\"n\">nesCarts<\/span><span class=\"x\"> <\/span><span class=\"o\">:=<\/span><span class=\"x\"> <\/span><span class=\"p\">[]<\/span><span class=\"kt\">string<\/span><span class=\"p\">{<\/span><span class=\"s\">\"Battletoads\"<\/span><span class=\"p\">,<\/span><span class=\"x\"> <\/span><span class=\"s\">\"Mega Man 1\"<\/span><span class=\"p\">,<\/span><span class=\"x\"> <\/span><span class=\"s\">\"Clash at Demonhead\"<\/span><span class=\"p\">}<\/span><span class=\"x\">\n<\/span><span class=\"n\">numberOfCarts<\/span><span class=\"x\"> <\/span><span class=\"o\">:=<\/span><span class=\"x\"> <\/span><span class=\"nb\">len<\/span><span class=\"p\">(<\/span><span class=\"n\">nesCarts<\/span><span class=\"p\">)<\/span><span class=\"x\">\n\n<\/span><span class=\"n\">anonymousStruct<\/span><span class=\"x\"> <\/span><span class=\"o\">:=<\/span><span class=\"x\"> <\/span><span class=\"k\">struct<\/span><span class=\"x\"> <\/span><span class=\"p\">{<\/span><span class=\"x\">\n\t<\/span><span class=\"n\">NESCarts<\/span><span class=\"x\"> \t<\/span><span class=\"p\">[]<\/span><span class=\"kt\">string<\/span><span class=\"x\">\n\t<\/span><span class=\"n\">numberOfCarts<\/span><span class=\"x\">   <\/span><span class=\"kt\">int<\/span><span class=\"x\">\n<\/span><span class=\"p\">}{<\/span><span class=\"x\">\n\t<\/span><span class=\"n\">nesCarts<\/span><span class=\"p\">,<\/span><span class=\"x\">\n\t<\/span><span class=\"n\">numberOfCarts<\/span><span class=\"p\">,<\/span><span class=\"x\">\n<\/span><span class=\"p\">}<\/span><\/code><\/pre><\/figure>\n\n<p>Notice how I\u2019m using not commas in the declaration of the struct, but I\u2019m using them when initializing values in the struct. Keep this in mind when you\u2019re using them.<\/p>\n\n","pubDate":"Thu, 08 Jan 2015 05:12:06 +0000","link":"http:\/\/kelcecil.com\/golang\/2015\/01\/08\/anonymous-structs-in-go.html","guid":"http:\/\/kelcecil.com\/golang\/2015\/01\/08\/anonymous-structs-in-go.html","category":["golang","structs","golang"]},{"title":"First Post of a New Blog","description":"<p>This is a test post of my new blog using Octopress. I haven\u2019t blogged in a very long time, and I think it\u2019s time to give blogging another shot.<\/p>\n\n<p>If you\u2019re interested in a Docker container for Octopress that deploys your repository containing your Octopress files and uses a quick, production-ready web server (gwan), then check out my <a href=\"https:\/\/github.com\/kelcecil\/docker-octopress\">docker-octopress image at Github<\/a>. I\u2019ll blog in detail about it later, but I thought I\u2019d mention it now to include something of value in what is essentially a long-winded \u201cFIRST!!!\u201d post.<\/p>\n","pubDate":"Tue, 06 Jan 2015 18:34:55 +0000","link":"http:\/\/kelcecil.com\/2015\/01\/06\/first-post-of-a-new-blog.html","guid":"http:\/\/kelcecil.com\/2015\/01\/06\/first-post-of-a-new-blog.html"}]}}