{"id":968,"date":"2022-02-14T12:00:00","date_gmt":"2022-02-14T20:00:00","guid":{"rendered":"https:\/\/letsbuildroboticswithshadow8472.com\/?p=968"},"modified":"2022-02-14T00:41:07","modified_gmt":"2022-02-14T08:41:07","slug":"containerized-development-environment","status":"publish","type":"post","link":"https:\/\/letsbuildroboticswithshadow8472.com\/index.php\/2022\/02\/14\/containerized-development-environment\/","title":{"rendered":"Containerized Development Environment"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Good Morning from my Robotics Lab! This is Shadow_8472, and today I am building my own dice bot for Discord using containers. Let\u2019s get started!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"overview\">Overview<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In last week\u2019s post, I learned how difficult a Discord dice roller is to find that is either already in a container or suitable to install into one. However, I did develop my skills along the way, and I believe I\u2019m ready to make a bot of my own from scratch.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"development-environment\">Development Environment<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">None of my machines had Python on them (except perhaps excluding the odd Raspberry Pi I have laying around), so the first order of business was to set up my own environment inside a container. There are a number of base images for running Python, but for development, I chose the latest official Python.<\/p>\n\n\n\n<pre class=\"wp-block-verse\">Podman pull python:latest<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">I went back and forth several times with the geometry of my bot project. I ended up stashing my work last week into a directory and making another to hold this round. When I was done, I had three files of consequence: Dockerfile, requirements.txt file, and a directory called home.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When I tell Buildah to make an image, it first goes to the Dockerfile:<\/p>\n\n\n\n<pre class=\"wp-block-verse\">FROM python:latest\nCOPY requirements.txt .\nRUN python -m pip install -r requirements.txt<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This takes the Python image, copies in requirements.txt, and references it to install any dependencies that don\u2019t come with Python by default, namely as discord.py. As such, requirements.txt had a single line:<\/p>\n\n\n\n<pre class=\"wp-block-verse\">discord<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Container base images leave out a lot of quality of life programs one might expect on a normal Linux install, like a text editor. That\u2019s where the home directory comes in.<\/p>\n\n\n\n<pre class=\"wp-block-verse\">podman run -t -v \/home\/shadow8472\/&lt;bot project&gt;\/home:\/root:Z -i dice_development:latest \/bin\/bash<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This command has Podman use that image to make a container, mount that home directory into the container as \/root (:Z is to tell SELinux it\u2019s all good), and start a bash shell. From here, I can<\/p>\n\n\n\n<pre class=\"wp-block-verse\">podman attach &lt;container name&gt;\ncd \/root<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">and run the bot\u2019s .py file. With the shared directory, I can edit it from the relative comfort of the host computer, ButtonMash, and go straight to running it inside the container. Best of all, the container will keep running with the bot if my connection to the host is broken, like if the network drops out or if I willingly close the terminal window. When I want to keep working, I can reattach the container.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Login token as environment variable: will my mental innovation of using the dockerfile to assemble it into a format Python understands work?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"development\">Development<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">I don\u2019t have many comments about the actual development of the bot. It\u2019s been a while since I actually programmed, and it\u2019s been longer still since Python. I learned the basics of async programming a few years ago, and discord.py is building on that introduction, but I\u2019m not setting out to master it just yet.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On my way to first stable \u201crelease,\u201d I was coding up a loop meant to fill an array with die rolls. A bit of C++ grammar slipped in, and only after asking around did I identify it on my own and fix it. Another time, I coded an <strong>echo!<\/strong> function to practice passing command extensions into my code.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Most of my time went into constantly overhauling the internal logic. My early prototype was hardcoded to build its output string one die at a time, but I had to rework the back end to store the dice as they came in so I could sum them up and display that separately. All this was done while trying to keep it in a near-functional state.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But there are times a feature needs invasive re-working. I have some code in my comments that eliminates string manipulation from a function that should only be dealing with numbers. I\u2019ve tried learning a popular version control system called Git in the past, but I can feel that I might actually stick with it this time. I\u2019ve started reviewing commands, but I have yet to start using it as of writing.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"side-project\">Side Project<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">My week started off rough. I found my Derpy Chips workstation with a blank screen when I went to pull up last week\u2019s post for some last minute proofreading. Initial diagnostics showed the screen blanks 0-30 seconds after making a picture from waking up. I got some help pouring over journalctrl and Xorg logs, but everything looked normal. The problem persisted through rebooting, pulling the GPU (graphics card), booting to an external drive, driving the monitor with my laptop, and even using a DVI cable instead of an HDMI. Final diagnostics turned up a dying backlight. I re-enlisted a personal museum piece \u2013a vintage cathode ray tube model\u2013 to fill in until a suitable replacement can be procured.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"3d-printing\">3D Printing<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Turns out that while I can play Minecraft just fine on integrated graphics, Slic3r pushes a few too many polygons for a smooth experience. I can\u2019t run the old monitor off the graphics card because the card doesn\u2019t have a VGA connector. Until I get a replacement monitor \u2013or at the very least an adapter\u2013 I\u2019ll be stuck with printing pre-made .stl objects or else installing Slic3r on another workstation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">What I did instead this week was make my own profile picture for the dice bot. I found a few dice I used to role play with and set them up in my photo booth. I even used a bead from printing the Z-braces to support a die in the back. I tweaked the picture a bit in GIMP to make it look more like the actual dice before uploading it for my friends\u2019 enjoyment. It was not fun to fight the .jpg compression the entire way.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"takeaway\">Takeaway<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Programming is a completely different side of technology than systems management. It\u2019s been a rewarding experience assembling my own environment to work in. It will need even more tweaking if\/when I need to adapt it for use with an IDE, but those are for people who either already know everything that\u2019s going or or those who don\u2019t care to learn what\u2019s going on at a basic level.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"final-question\">Final Question<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Async functions are weird. I am after a small function to both log and send a response message. How do I pass an async call to another function? Am I even asking the right question?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Good Morning from my Robotics Lab! This is Shadow_8472, and today I am building my own dice bot for Discord using containers. Let\u2019s get started! Overview In last week\u2019s post, I learned how difficult a Discord dice roller is to find that is either already in a container or suitable to install into one. However, &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/letsbuildroboticswithshadow8472.com\/index.php\/2022\/02\/14\/containerized-development-environment\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Containerized Development Environment&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_forum_subforum_count":0,"footnotes":""},"categories":[92,2,9],"tags":[],"class_list":["post-968","post","type-post","status-publish","format-standard","hentry","category-discord-bot","category-linux","category-programming"],"_links":{"self":[{"href":"https:\/\/letsbuildroboticswithshadow8472.com\/index.php\/wp-json\/wp\/v2\/posts\/968","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/letsbuildroboticswithshadow8472.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/letsbuildroboticswithshadow8472.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/letsbuildroboticswithshadow8472.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/letsbuildroboticswithshadow8472.com\/index.php\/wp-json\/wp\/v2\/comments?post=968"}],"version-history":[{"count":2,"href":"https:\/\/letsbuildroboticswithshadow8472.com\/index.php\/wp-json\/wp\/v2\/posts\/968\/revisions"}],"predecessor-version":[{"id":971,"href":"https:\/\/letsbuildroboticswithshadow8472.com\/index.php\/wp-json\/wp\/v2\/posts\/968\/revisions\/971"}],"wp:attachment":[{"href":"https:\/\/letsbuildroboticswithshadow8472.com\/index.php\/wp-json\/wp\/v2\/media?parent=968"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/letsbuildroboticswithshadow8472.com\/index.php\/wp-json\/wp\/v2\/categories?post=968"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/letsbuildroboticswithshadow8472.com\/index.php\/wp-json\/wp\/v2\/tags?post=968"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}