
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
 <channel>
   <title>Room Full of Mirrors</title>
   <link>https://jrfom.com/</link>
   <description>Recent content on Room Full of Mirrors</description>
   <generator>Hugo -- gohugo.io</generator>
   <language>en-us</language>
   <copyright>Copyright ©{year} James Sumners. All rights reserved.</copyright>
   <lastBuildDate>Wed, 23 Apr 2025 16:30:00 -0400</lastBuildDate>
   
       <atom:link href="https://jrfom.com/index.xml" rel="self" type="application/rss+xml" />
   
   
     <item>
       <title>Erosion Management Services Review</title>
       <link>https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/</link>
       <pubDate>Wed, 23 Apr 2025 16:30:00 -0400</pubDate>
       
       <guid>https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/</guid>
       <description>&lt;p&gt;This post contains two reviews for a company I hired to deal with an erosionproblem in my yard. The original review resulted in the company coming backto improve their work. They did not ask me to update, nor remove, my originalreview. But I think it is important to provide an update, Google reviewswouldn&amp;rsquo;t even let me write all of the words I originally wanted to write (Ihad to revise my review a bit to meet their word/character limit), andarchive.org is not allowed to archive Google reviews pages. So the originalreview will be replicated below, and then my updated review (which I willreplace my original review with on Google&amp;rsquo;s site).&lt;/p&gt;&lt;h2 id=&#34;original-review&#34;&gt;  Original Review  &lt;a href=&#34;#original-review&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;blockquote&gt;&lt;p&gt;This review was left in February of 2025 for work performed in June (or July)of 2024. The images referenced in the review are included at the bottom of thissection.&lt;/p&gt;&lt;p&gt;First things first: I didn&amp;rsquo;t want to write this review because there weremistakes made on both sides; I was going to let bygones be bygones. Combinedwith the overall summary that they did better than the first company I hiredfor the same work, this is why I am giving a 2 instead of a 1 star rating. Nowon to the actual review.&lt;/p&gt;&lt;p&gt;In early 2022 I contacted this company to spec out an erosion project in myfront yard. A year prior, I had had a landscaping company put in a berm anddrain to catch and divert water from washing out my yard. That berm failed dueto shoddy work. So the project manager came out to my house, we reviewed myproject, and he made several suggestions about what to do. Unfortunately, I hadto put the project on hold a couple of days later due to being caught up in amass layoff. Fast forward to 2023 when I have had a new job for a while and amback in a financial position to do this work: I call them back to say I&amp;rsquo;m readyto start the project again. Initially, they just wanted to come out and do it.But it had been over a year, so I was adamant that they come out and re-reviewthe project. That should have been my warning, but the project manager came outand looked at it again with me. He clearly didn&amp;rsquo;t take any notes the firsttime (which seems to be modus operandi), because when I asked about some of thedetails HE had suggested the last time, he acted like I was asking forsomething unheard of.&lt;/p&gt;&lt;p&gt;Anyway, we pushed through with the project. They rebuilt the berm, added somesmall river rocks around the drain, tied another drain in from further up thehill, and added a French drain around one corner of my driveway. Once the workwas completed, the crew simply vanished. They never knocked on my door to letme know they were finished. And the project manager had zero intention ofcoming back to review the work; he was content to sign-off on the work from thepictures his crew sent him. When I asked him to come out and review the workwith me, I got a very distinct impression that I was inconveniencing him. Buthe did eventually come back out, and we agreed that some things had beenmissed. His crew came back out, touched up the missing parts, and I decided tolet the project be finished.&lt;/p&gt;&lt;p&gt;The rocks around the drain, which was the project manager&amp;rsquo;s suggestion duringour very first review, were, as I understood the suggestion, meant to reinforcethe berm and alleviate sediment blocking the drain. We didn&amp;rsquo;t really have anysignificant rains until early this year (2025), so it never got thoroughlytested. Well, the first hard, long, rain we got has resulted in the bermoverflowing, and it getting washed out along with my yard. Turns out, they hadcovered up most of the drain with landscaping cloth and the rocks. Basically,they half-assed it. I just had to remove the rocks and cloth in order todetermine if the drain was blocked ahead of our next forecasted heavy rain.&lt;/p&gt;&lt;p&gt;Not only that, but the French drain that was put in was supposed to catch theheavy runoff I have in that area and divert it to a lower location in my yard.As can be seen in the attached pictures, this isn&amp;rsquo;t quite working as intended.I suppose it is catching most of it, but there is still washout happening, soit clearly isn&amp;rsquo;t sufficient.&lt;/p&gt;&lt;p&gt;In addition to all of that, the grass seed they put down, and covered quitepoorly, never grew. I spent the last few warm months of 2024 meticulouslyseeding and growing as much grass as I could on my own. Given it was so late,there&amp;rsquo;s still a lot to do this spring. What I discovered, is that they didn&amp;rsquo;teven seed the grass properly. They just threw some handfuls of seed on theground and tossed some straw on top of it. They didn&amp;rsquo;t rake out any of theunfiltered soil they put down in order to give the seed something to embedinto. And they didn&amp;rsquo;t give me any instructions about how to maintain the workto get any seed to grow.&lt;/p&gt;&lt;p&gt;In summary, I have to make a bunch of repairs myself because they didn&amp;rsquo;t dothings right.&lt;/p&gt;&lt;/blockquote&gt;                &lt;style&gt;      .image-gallery {        display: grid;        grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));        gap: 0.5em;      }    &lt;/style&gt;    &lt;div class=&#34;image-gallery&#34;&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;original-photos/001.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/original-photos/001_hu6773fda97d7b6823754202176ce629fc_107700_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;original-photos/0010.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/original-photos/0010_huc4c96eb4c9875ba28e5a40ef3de7cade_1808526_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;original-photos/0011.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/original-photos/0011_hu381629df638fdbf14dc82bd95372283b_1715719_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;original-photos/0012.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/original-photos/0012_hucc862b1ba036aeafbb0e7c508c5f219d_1658895_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;original-photos/0013.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/original-photos/0013_hu64c85a442da03b75782d1587a7d9ba76_1665155_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;original-photos/0014.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/original-photos/0014_hu050fa60d2b7c9ae2b2ee8f2878908b7f_1450877_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;original-photos/002.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/original-photos/002_hu6773fda97d7b6823754202176ce629fc_106828_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;original-photos/003.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/original-photos/003_hu6773fda97d7b6823754202176ce629fc_115972_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;original-photos/004.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/original-photos/004_hu6773fda97d7b6823754202176ce629fc_132153_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;original-photos/005.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/original-photos/005_hu6773fda97d7b6823754202176ce629fc_125564_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;original-photos/006.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/original-photos/006_hu6773fda97d7b6823754202176ce629fc_103813_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;original-photos/007.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/original-photos/007_huae0301ea244b9aa8c562caeca81c6794_1658423_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;original-photos/008.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/original-photos/008_hu21f433fb22a1c52f2dff4f03594f3e47_1783019_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;      &lt;/div&gt;&lt;h2 id=&#34;updated-review&#34;&gt;  Updated Review  &lt;a href=&#34;#updated-review&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I&amp;rsquo;m revising my rating from 2 stars to 3 stars. I wanted to go up to 4, buta couple of disappointments, that I will cover shortly, prevent that.&lt;/p&gt;&lt;p&gt;After writing my original reivew, the company reached out to determine whatthey might be able to do to make things right. I scheduled a time for Mike tocome out and look at things with me. He agreed with me that the work was notsufficient. He actually took some notes, and had a crew out the next week tocorrect the issues. They built up a new berm, re-did the french drain and addeda swale to it, and put down erosion blanket to ensure the grass would have achance to grow. The next week, Mike came back out to review the work andadvise me about how to nuture it until it is settled in. He also mentioned hewould like to come back and apply hydroseed to the area just to make sure itreally takes.&lt;/p&gt;&lt;p&gt;Fast forward to April 2. I received a call from Mike in which he said he wouldbe out the following week (week of April 7) to take up the erosion blanketand apply the hydroseed. I said I was planning to take up the blanket that veryday, but would wait for his crew to get it done. The next week came and wentwithout any communication. So did the next, until I needed to get my grasscut before a trip. I spent 3 hours pulling the blanket, that I&amp;rsquo;m sure would beensignificantly easier two week earlier, and taking it off to the dump. I nevergot to cut my grass until the 23rd because that took up all the time and bodyI had available to get work done before my trip on the 17th. My back,unaccustomed to such work, was in pain and my finger tips and knees raw.Thankfully my back recovered over night, but I still started my trip withrecovery on the other parts. I was finally able to do the work I had plannedto do on the 2nd, today, the 23rd, and I still had deal with leftover blanketmaterial (and probably will for months or years to come).&lt;/p&gt;&lt;p&gt;Aside from some landscaping blanket blotting my, now ineffective, originalberm, the work looks great and seems to be solving the problem, albeitexacerbating another problem where the water now dumps out. I&amp;rsquo;m very pleasedto have my main issue seemingly solved. But I&amp;rsquo;m disappointed that promises Ididn&amp;rsquo;t ask for were never kept. Please don&amp;rsquo;t tell me you will do a thing andthen never even communicate that you aren&amp;rsquo;t able to.&lt;/p&gt;      &lt;div class=&#34;image-gallery&#34;&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/001.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/001_hu7129c3f9f28f5ddd00381529d21769d3_1596934_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/002.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/002_hu373ffad2e0447feb41eb5def26d73859_1313907_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/003.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/003_hue6b9272a7a0bd41d9b878a18c7b5fda2_1581886_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/004.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/004_hu985bdb8f302b22eb84831d8ae6e2ce6d_1708259_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/005.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/005_hud410613d9bbe4d04b6ff55c11a9e0c1a_1690140_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/006.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/006_hua11f9e9efae00325cef3de7717ea282d_1851854_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/007.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/007_hue57f2ce6d0b2b73458f61bc4fc2104c3_1474761_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/008.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/008_hu3e05e51a0a83bf46017df78075874f1a_1744090_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/009.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/009_hu69495046e1c4e202ed731b3edadd46c7_1575847_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/010.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/010_hu6680b83022ac3726076e9dad642235af_1206095_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/011.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/011_hu43dd6d12c15172a15b139db7a7211cc6_1685509_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/012.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/012_hu6e7bac6febe3414ef6ce1f63b91cd112_1094233_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/013.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/013_hu8f05161ba06ec4f6cb796a2db150671d_1502897_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/014.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/014_hu145af98bef0d7734e419ac05510b4e4e_1507413_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/015.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/015_huf39aa65784df2f3ff3b81e692b423905_1581751_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/016.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/016_hu8b7f65f8b286d3fc26ebccc07f2e8796_1519764_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/017.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/017_hu1ca91c327dd8dafa876f421d56a172b2_1504559_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/018.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/018_hu221ea98c0c53c552a9e435caad94da1f_1218605_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/019.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/019_hu50976d00a55e9553ef26ffab66d9f2fe_1323843_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/020.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/020_huc39c94947229acac7ef8ff3a0c8baaef_1446916_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;updated-review-photos/021.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2025/04/23/erosion-mgmt-svs/updated-review-photos/021_huefac7cfae8046d34c873ca3d4e2b55b5_1442384_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;      &lt;/div&gt;</description>
     </item>
   
     <item>
       <title>Silca&#39;s Reviews System And Waxer</title>
       <link>https://jrfom.com/posts/2024/06/23/silca-waxer-review/</link>
       <pubDate>Sun, 23 Jun 2024 20:00:00 -0400</pubDate>
       
       <guid>https://jrfom.com/posts/2024/06/23/silca-waxer-review/</guid>
       <description>&lt;p&gt;I have been using Silca&amp;rsquo;s &lt;a href=&#34;https://silca.cc/products/secret-chain-wax-blend?variant=39433348677730&#34;&gt;hot melt wax&lt;/a&gt; since April of 2022.It&amp;rsquo;s great stuff, and I&amp;rsquo;ve written a &lt;a href=&#34;https://jrfom.com/posts/2022/05/08/chain-waxing/&#34;&gt;thorough article&lt;/a&gt;on it that details my whole setup and the tricks I have learned about theprocess. So I was rather excited when Silca announced their dedicated&lt;a href=&#34;https://silca.cc/products/chain-waxing-system?utm_source=yotpo&amp;amp;utm_medium=email&amp;amp;utm_campaign=anonymous&amp;amp;ref=yotpo_7&#34;&gt;wax warmer&lt;/a&gt;. I put my name on the waiting list and got one assoon as I could. Unfortunately, I am disappointed with the product and tookthe time to write a review for it to give some perspective for others toconsider. I wrote the review on June 13, 2024 and it &lt;em&gt;still&lt;/em&gt; does not show upon the product page as of June 23, 2024. I have used multiple browsers, withephemeral caches (&amp;ldquo;incognito mode&amp;rdquo;), to verify this, so I&amp;rsquo;m posting here alongwith some information on Silca&amp;rsquo;s review system.&lt;/p&gt;&lt;h2 id=&#34;silcas-review-system&#34;&gt;  Silca&amp;rsquo;s Review System  &lt;a href=&#34;#silcas-review-system&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;After a couple of days of my review not being posted, I contacted Silca&amp;rsquo;scustomer support asking why the review is not present on their site. Honestly,I wasn&amp;rsquo;t sure I would get a response, but I did. They said that they:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&amp;hellip; have a new review system and it selects random reviews to display androtates them through the website. It does all of this automatically so noone has to worry about putting them on the website or choosing what toput up.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;I think it is fair to try and lessen the maintenance burden on the team, butthis review system has the consequence of presenting misleading ratings. As Imentioned, my review still does not show up on the site. I am able to verifythis by viewing the &lt;a href=&#34;https://silca.cc/products/chain-waxing-system?utm_source=yotpo&amp;amp;utm_medium=email&amp;amp;utm_campaign=anonymous&amp;amp;ref=yotpo_7&#34;&gt;product page&lt;/a&gt; and selecting the option toshow all two star reviews, as my review was ranked with two stars&lt;/p&gt;&lt;p&gt;Below are two screenshots. The first one shows the reviews portion of theproduct page as it is initially loaded. The second one shows it with the twostars only filter applied. There are a few things to notice about thesescreenshots:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The overall rating shown is a five star rating because the system rounds upthe 4.8 rating and shows it as a full five.&lt;/li&gt;&lt;li&gt;It is claiming there are only 96 reviews that contribute to this rating.&lt;/li&gt;&lt;li&gt;There is only &lt;em&gt;one&lt;/em&gt; 2-star review, and it isn&amp;rsquo;t mine.&lt;/li&gt;&lt;/ol&gt;                &lt;style&gt;      .image-gallery {        display: grid;        grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));        gap: 0.5em;      }    &lt;/style&gt;    &lt;div class=&#34;image-gallery&#34;&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;screenshots/all-reviews.jpg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2024/06/23/silca-waxer-review/screenshots/all-reviews_hub08553aa6968665df8e4ccd9e01923fe_1449066_480x0_resize_q80_box.jpg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;screenshots/two-star-reviews.jpg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2024/06/23/silca-waxer-review/screenshots/two-star-reviews_hub08553aa6968665df8e4ccd9e01923fe_1309306_480x0_resize_q80_box.jpg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;      &lt;/div&gt;&lt;p&gt;Let me be clear: &lt;strong&gt;&lt;em&gt;THIS REVIEW SYSTEM IS NOT TRUSTWORTHY&lt;/em&gt;&lt;/strong&gt;. I think it borderson lying, whether intentionally or not. Silca should be complaining to theauthors of this system or outright replacing it (while retaining the datasubmitted by customers).&lt;/p&gt;&lt;p&gt;I appreciate that the support team was responsive to my inquries and was kindenough to go out of their way to send me a copy of the review I originallyposted. I am definitely not placing blame on them. I place the blame squarelyon the chosen tool, and am giving the benefit of the doubt that those whochose it missed this when they were evaluating it.&lt;/p&gt;&lt;h2 id=&#34;original-review&#34;&gt;  Original Review  &lt;a href=&#34;#original-review&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The review I submitted to Silca is as follows:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;title: I wish it were up to the Silca standard&lt;/p&gt;&lt;p&gt;This is the first Silca product I have been disappointed with. Upfront,the good parts: it&amp;rsquo;s affordable, well built, and the PID controller is great(and is the reason I bought it). But that&amp;rsquo;s where it ends for me.&lt;/p&gt;&lt;p&gt;I have used this tool to was my chain three times, and have since gone backto my dedicated esthetician wax warmer. The reasons why:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The chain hanger does not attach to the base. You should be able to screwit on to the bottom in order to make it a single unit.&lt;/li&gt;&lt;li&gt;The pot is way too small. It cannot hold a full bag of the Silca waxpellets. That might be okay if they sold a bag you could simply dump into itwithout thinking, but as it is you have to guess if you&amp;rsquo;ve put in just enoughsuch that it won&amp;rsquo;t overflow when you displace it by putting the chain in. Andputting the chain in is rather difficult due to the small size. You must getthe chain on the cable coupler &lt;em&gt;just right&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;There&amp;rsquo;s no clip/ledge to hold the cable coupler out of the pot while thechain is treated. You have to come up with some other solution, e.g. ascrewdriver.&lt;/li&gt;&lt;li&gt;If you try to warm the wax on the baseline 75º temperature, it will takewell over an hour for all of the wax to melt and be ready for the chain. Anddo not attempt to put the chain on top of the wax so that it warms up at thesame time as the wax. You&amp;rsquo;ll end up with a goopy mess due to the slowwarming time.&lt;/li&gt;&lt;li&gt;The buttons are difficult to use. They are capacitive touch buttons, andare very finicky to register touch.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;If you&amp;rsquo;re still interested in this product, I recommend waiting for the nextrevision (or two).&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&#34;./review-pics/IMG_4333.jpeg&#34;&gt;review photo 1&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;./review-pics/IMG_4334.jpeg&#34;&gt;review photo 2&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;./review-pics/IMG_4335.jpeg&#34;&gt;review photo 3&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;./review-pics/IMG_4336.jpeg&#34;&gt;review photo 4&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;./review-pics/IMG_4337.jpeg&#34;&gt;review photo 5&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;./review-pics/IMG_4338.jpeg&#34;&gt;review photo 8&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;h2 id=&#34;summary&#34;&gt;  Summary  &lt;a href=&#34;#summary&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I really like Silca&amp;rsquo;s products as a general rule. I have no intention ofusing any other wax, and I &lt;em&gt;love&lt;/em&gt; their &lt;a href=&#34;https://silca.cc/collections/bar-tape-1/products/nastro-cuscino-bar-tape&#34;&gt;bar tape&lt;/a&gt;. I would even bewilling to give the wax warmer another shot if they address all of the issuesI have outlined. But they really, &lt;em&gt;really&lt;/em&gt;, need to fix their reviews system.Having to replicate it here because their site hides reviews and omits themfrom the rating calculations is unacceptable.&lt;/p&gt;</description>
     </item>
   
     <item>
       <title>Managing Node.js Processes</title>
       <link>https://jrfom.com/posts/2023/12/15/node-process-management/</link>
       <pubDate>Fri, 15 Dec 2023 11:45:00 -0400</pubDate>
       
       <guid>https://jrfom.com/posts/2023/12/15/node-process-management/</guid>
       <description>&lt;p&gt;Recently, I posted to Twitter: &amp;ldquo;why do people still use pm2?&amp;rdquo; The post garneredmuch more attention than I expected it to, and I was asked by several people:&amp;ldquo;what is your alternative?&amp;rdquo; This article will outline why I think using &lt;code&gt;pm2&lt;/code&gt;is unnecessary and what I think should be done instead.&lt;/p&gt;&lt;h2 id=&#34;what-is-pm2&#34;&gt;  What Is PM2?  &lt;a href=&#34;#what-is-pm2&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;pm2&lt;/code&gt;, per &lt;a href=&#34;https://github.com/Unitech/pm2/blob/311c53298448fc4575fc689c4943692a664373ad/README.md?plain=1#L35&#34;&gt;their readme&lt;/a&gt;, is:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&amp;hellip; a production process manager for Node.js applications with a built-inload balancer. It allows you to keep applications alive forever, to reloadthem without downtime and to facilitate common system admin tasks.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;In short: it&amp;rsquo;s a tool that launches your Node.js based application, watchesit to detect when it has failed, and restarts it upon failure.&lt;/p&gt;&lt;p&gt;It also provides some measure of application performance monitoring (APM). Iwill not be focusing on the APM aspect in this article. Instead, I will focuson the primary use case as described in the quote and what I have seen whendealing with issues around &lt;code&gt;pm2&lt;/code&gt; in my open source work. What I&amp;rsquo;ll say aboutthe APM piece is that there are plenty of tools, e.g.&lt;a href=&#34;https://opentelemetry.io&#34;&gt;OpenTelemetry&lt;/a&gt;, that can provide equivalent or better insights.&lt;/p&gt;&lt;h2 id=&#34;pid-1&#34;&gt;  PID 1  &lt;a href=&#34;#pid-1&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Process_management_(computing)&#34;&gt;Process management&lt;/a&gt; is how modern operating systems (OSes) providemultitasking. Without process management, we&amp;rsquo;d boot our computers into a singleapplication, do work, close the application, and the computer would shutdown(as an over simplification). On a Linux based system, this translates into:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The kernel is started via the bootloader.&lt;/li&gt;&lt;li&gt;The kernel initializes itself and then spawns a defined application.&lt;/li&gt;&lt;li&gt;The application spawned by the kernel is a process manager and isassigned to &lt;a href=&#34;https://en.wikipedia.org/wiki/Process_identifier&#34;&gt;PID 1&lt;/a&gt; (process identifier 1).&lt;/li&gt;&lt;li&gt;All other applications, from a CLI shell to a web browser, are spawned fromand managed by the PID 1 process.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;There are many different process managers. A short list of process managersused by various Linux (and BSD) systems to provide PID 1 is:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/UNIX_System_V&#34;&gt;System V&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/OpenRC&#34;&gt;OpenRC&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://wiki.gentoo.org/wiki/S6_and_s6-rc-based_init_system&#34;&gt;S6&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Runit&#34;&gt;runit&lt;/a&gt; (my personal preference)&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Systemd&#34;&gt;systemd&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&#34;why-pm2&#34;&gt;  Why PM2?  &lt;a href=&#34;#why-pm2&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Great, so we know what a process manager is, that &lt;code&gt;pm2&lt;/code&gt; is one, and thatOSes ship with one probably found in that short list. So why does &lt;code&gt;pm2&lt;/code&gt; existif we already have a process manager at our disposal? Personally, I think itis due to a few primary reasons:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The majority of people developing Node.js applications for server systemsare not experts on application deployment.&lt;/li&gt;&lt;li&gt;Software developers like to use tools written in the same language they arewriting their own sofware in.&lt;/li&gt;&lt;li&gt;That part about &amp;ldquo;a built-in load balancer&amp;rdquo; in the &lt;code&gt;pm2&lt;/code&gt; description quotedabove.&lt;/li&gt;&lt;li&gt;Someone wrote an article that suggested using it, the article became popular,and eventually turned in to gospel passed down through the ages.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Consider the following basic web server application:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;use strict&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;server&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;fastify&amp;#39;&lt;/span&gt;)({ &lt;span style=&#34;color:#a6e22e&#34;&gt;logger&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt; })&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;server&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;route&lt;/span&gt;({&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;path&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;method&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;get&amp;#39;&lt;/span&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;handler&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;req&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;res&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;res&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;send&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;hello world&amp;#39;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;})&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;server&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;listen&lt;/span&gt;({ &lt;span style=&#34;color:#a6e22e&#34;&gt;port&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;process&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;env&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;PORT&lt;/span&gt; })&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;pm2&lt;/code&gt; makes it easy to start, and keep running, such an application:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ export PORT&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;8080&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ pm2 start index.js&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It also provides a simple switch to enable load balancing, what it calls&amp;ldquo;cluster mode,&amp;rdquo; that will utilize multiple CPUs (or CPU cores) for the server:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ export PORT&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;8080&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ pm2 start index.js -i &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# where 2 is the number of CPUs to use&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;From there, it provides tooling for inspecting and managing logs and viewingmetrics around the process. You can consult their documentation for moreinformation on these features.&lt;/p&gt;&lt;h2 id=&#34;why-not-pm2&#34;&gt;  Why Not PM2?  &lt;a href=&#34;#why-not-pm2&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The short answer is: you already have the tools to accomplish the primaryfunction of &lt;code&gt;pm2&lt;/code&gt;. We&amp;rsquo;ll see that later when I present my suggestedalternative. For now, let&amp;rsquo;s inspect how &lt;code&gt;pm2&lt;/code&gt; does some of the things it does.&lt;/p&gt;&lt;p&gt;First, it wraps the application in what it calls a&lt;a href=&#34;https://github.com/Unitech/pm2/blob/311c53298448fc4575fc689c4943692a664373ad/lib/ProcessContainer.js&#34;&gt;&lt;code&gt;ProcessContainer&lt;/code&gt;&lt;/a&gt;. This container starts the applicationin a subprocess with an IPC channel, &lt;a href=&#34;https://en.wikipedia.org/wiki/Monkey_patch&#34;&gt;monkey patches&lt;/a&gt; &lt;code&gt;process.stdout&lt;/code&gt;and &lt;code&gt;process.stdin&lt;/code&gt;, registers handler for typical process signals, andregisters handlers for &lt;code&gt;uncaughtException&lt;/code&gt; and &lt;code&gt;unhandledRejection&lt;/code&gt;. I recommendreading through the linked container source code to understand how &lt;code&gt;pm2&lt;/code&gt; ishandling your process. Pay close attention to the &lt;code&gt;stdout&lt;/code&gt; and &lt;code&gt;stdin&lt;/code&gt; patches.We see regularly see &lt;a href=&#34;https://github.com/pinojs/pino/issues?q=is%3Aissue+sort%3Aupdated-desc+pm2+is%3Aclosed&#34;&gt;issues in Pino&lt;/a&gt; regarding monkey patched&lt;code&gt;stdout&lt;/code&gt;, with several of them being due to the patching done by &lt;code&gt;pm2&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Second, &lt;code&gt;pm2&lt;/code&gt; enables &amp;ldquo;load balancing&amp;rdquo; through the use of Node.js&amp;rsquo;s&lt;a href=&#34;https://nodejs.org/dist/latest/docs/api/cluster.html&#34;&gt;cluster module&lt;/a&gt;. This module implements a round-robin load balancingalgorithm, which &lt;code&gt;pm2&lt;/code&gt; seems to rely upon, as its primary balancing algorithm.The result is all network connections really going to a single process, the&lt;code&gt;pm2&lt;/code&gt; process, and then getting balanced to one of the forked processes. Whilethe overhead introduced here may be negligible if &lt;code&gt;pm2&lt;/code&gt; is only being used tomanage a singular application, I highly doubt it remains so when multipleapplications are being managed by &lt;code&gt;pm2&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Ultimately, using &lt;code&gt;pm2&lt;/code&gt; to manage your process means you have wrapped yourNode.js application up in another Node.js application thereby inheriting anyperformance penalties of that parent application in addition to your ownapplication&amp;rsquo;s performance characteristics.&lt;/p&gt;&lt;h2 id=&#34;what-instead&#34;&gt;  What Instead?  &lt;a href=&#34;#what-instead&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Assuming the application is being deployed to a full system, e.g. &amp;ldquo;bare metal&amp;rdquo;or some sort of virtual machine or VPS, we should utilize the OS&amp;rsquo;s nativeprocess manager. A typical deployment host in this sort of setup is&lt;a href=&#34;https://debian.org/&#34;&gt;Debian&lt;/a&gt;, which, at this time, uses &lt;code&gt;systemd&lt;/code&gt; as its process manager.&lt;/p&gt;&lt;p&gt;Recall that I mentioned &lt;code&gt;pm2&lt;/code&gt; adds handlers for process signals and processerrors. In order for our application to work correctly with a typical processmanager we need to update it in the same manner that &lt;code&gt;pm2&lt;/code&gt; is doingautomatically:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;use strict&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;server&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;fastify&amp;#39;&lt;/span&gt;)({ &lt;span style=&#34;color:#a6e22e&#34;&gt;logger&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt; })&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;handleSignal&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;sig&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;server&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;info&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;`handling signal &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;sig&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;server&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;close&lt;/span&gt;()&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;SIGINT&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;SIGTERM&amp;#39;&lt;/span&gt;].&lt;span style=&#34;color:#a6e22e&#34;&gt;forEach&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;sig&lt;/span&gt; =&amp;gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;process&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;on&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;sig&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;handleSignal&lt;/span&gt;))&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;process&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;on&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;uncaughtException&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;error&lt;/span&gt; =&amp;gt; {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;server&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;warn&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;got uncaughtException&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;error&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;server&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;close&lt;/span&gt;()&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;})&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;process&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;on&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;unhandledRejection&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;error&lt;/span&gt; =&amp;gt; {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;server&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;warn&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;got unhandledRejection&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;error&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;server&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;close&lt;/span&gt;()&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;})&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;server&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;route&lt;/span&gt;({&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;path&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;method&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;get&amp;#39;&lt;/span&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;handler&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;req&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;res&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;res&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;send&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;hello world&amp;#39;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;})&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;server&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;listen&lt;/span&gt;({ &lt;span style=&#34;color:#a6e22e&#34;&gt;port&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;process&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;env&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;PORT&lt;/span&gt; })&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Subsequently, we can configure the process manager to manage the application:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Add a new unprivilged user for our application:&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;adduser --system myapp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Create a deployment location for the app:&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir -p /opt/apps/myapp &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; chown myapp /opt/apps/myapp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Deploy the app:&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd /opt/apps/myapp &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; tar xcf /tmp/myapp.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Add a service description file as &lt;code&gt;/etc/systemd/system/myapp.service&lt;/code&gt;:&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;Unit&lt;/span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Description&lt;/span&gt;=&lt;span style=&#34;color:#a6e22e&#34;&gt;My&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Cool&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Web&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Server&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Requires&lt;/span&gt;=&lt;span style=&#34;color:#a6e22e&#34;&gt;network&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;target&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;Service&lt;/span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Type&lt;/span&gt;=&lt;span style=&#34;color:#a6e22e&#34;&gt;simple&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Restart&lt;/span&gt;=&lt;span style=&#34;color:#a6e22e&#34;&gt;always&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;RestartSec&lt;/span&gt;=&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;User&lt;/span&gt;=&lt;span style=&#34;color:#a6e22e&#34;&gt;myapp&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Group&lt;/span&gt;=&lt;span style=&#34;color:#a6e22e&#34;&gt;nogroup&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;WorkingDirectory&lt;/span&gt;=&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;opt&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;apps&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;myapp&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Environment&lt;/span&gt;=&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;PORT=8000&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;ExecStart&lt;/span&gt;=&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;usr&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;bin&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;node&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;opt&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;apps&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;myapp&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;index&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;js&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;Install&lt;/span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;WantedBy&lt;/span&gt;=&lt;span style=&#34;color:#a6e22e&#34;&gt;multi-user&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;target&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Activate the service:&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemctl daemon-reload&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemctl enable myapp&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemctl start myapp.service&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Verify the service is working:&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl http://127.0.0.1:8000/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Is this more involved? Yes, clearly. Normally this sort of thing will beautomated through some sort of infrastructure as code tool like&lt;a href=&#34;https://en.wikipedia.org/wiki/Ansible_(software)&#34;&gt;Ansible&lt;/a&gt;. However, we gain a few benefits from utilizing the sytemtools:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Anyone familiar with the standard OS tools will be familiar with how tomanage the service.&lt;/li&gt;&lt;li&gt;We gain limited process privileges through the use of system accounts.&lt;/li&gt;&lt;li&gt;Our service will start with the system according to the service configuration.&lt;/li&gt;&lt;li&gt;Logs are managed through the standard system log management, e.g.:&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;journalctl -u myapp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h3 id=&#34;clustering&#34;&gt;  Clustering  &lt;a href=&#34;#clustering&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;There is one caveat to the above example: it&amp;rsquo;s a singular process utilizingone CPU core according to the standard Node.js core usage. If we we want todedicate more resources to our application, we need to do a little more work.&lt;/p&gt;&lt;p&gt;First, we need to boot multiple instance of our application. With &lt;code&gt;systemd&lt;/code&gt;,we can rewrite our service using a target instead:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Create &lt;code&gt;/etc/systemd/system/myapp.target&lt;/code&gt; like:&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;Unit&lt;/span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Description&lt;/span&gt;=&lt;span style=&#34;color:#a6e22e&#34;&gt;My&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Cool&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Web&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Server&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Requires&lt;/span&gt;=&lt;span style=&#34;color:#a6e22e&#34;&gt;myapp&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;service&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;myapp&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;service&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;Install&lt;/span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;WantedBy&lt;/span&gt;=&lt;span style=&#34;color:#a6e22e&#34;&gt;multi-user&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;target&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Create &lt;code&gt;/etc/systemd/system/myapp@.service&lt;/code&gt; like:&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;Unit&lt;/span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Description&lt;/span&gt;=&lt;span style=&#34;color:#a6e22e&#34;&gt;My&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Cool&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Web&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Server&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;%&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;I&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Requires&lt;/span&gt;=&lt;span style=&#34;color:#a6e22e&#34;&gt;network&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;target&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;PartOf&lt;/span&gt;=&lt;span style=&#34;color:#a6e22e&#34;&gt;myapp&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;target&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;Install&lt;/span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;WantedBy&lt;/span&gt;=&lt;span style=&#34;color:#a6e22e&#34;&gt;myapp&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;service&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;Service&lt;/span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Type&lt;/span&gt;=&lt;span style=&#34;color:#a6e22e&#34;&gt;simple&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Restart&lt;/span&gt;=&lt;span style=&#34;color:#a6e22e&#34;&gt;always&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;RestartSec&lt;/span&gt;=&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;User&lt;/span&gt;=&lt;span style=&#34;color:#a6e22e&#34;&gt;myapp&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Group&lt;/span&gt;=&lt;span style=&#34;color:#a6e22e&#34;&gt;nogroup&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;WorkingDirectory&lt;/span&gt;=&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;opt&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;apps&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;myapp&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Environment&lt;/span&gt;=&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;PORT=800%I&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;ExecStart&lt;/span&gt;=&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;usr&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;bin&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;node&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;opt&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;apps&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;myapp&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;index&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;js&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Install the service:&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemctl daemon-reload&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemclt enable myapp.target&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Start the service as many times as CPU resources desired:&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemctl start myapp.target&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Verify they are running:&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl http://127.0.0.1:8001&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl http://127.0.0.1:8002&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;em&gt;Note that both instances will be restarted on system boot.&lt;/em&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Second, we need a way to load balance traffic to those instances. To do so,we should &lt;a href=&#34;https://github.com/fastify/fastify/blob/e3a07eaa444d0e769802195816d4e1718c2fc9ea/docs/Guides/Recommendations.md#use-a-reverse-proxy&#34;&gt;use a reverse proxy&lt;/a&gt;. My preference is to use&lt;a href=&#34;https://www.haproxy.org/&#34;&gt;HAProxy&lt;/a&gt;. In short, install HAProxy, provide a configuration likethe following one, and enable the service:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;frontend&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;myapp-proxy&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;bind&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0.0&lt;/span&gt;.&lt;span style=&#34;color:#ae81ff&#34;&gt;0.0&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;use_backend&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;myapp-backend&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;backend&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;myapp-backend&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;server&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;myapp1&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;127.0&lt;/span&gt;.&lt;span style=&#34;color:#ae81ff&#34;&gt;0.1&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;8001&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;server&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;myapp2&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;127.0&lt;/span&gt;.&lt;span style=&#34;color:#ae81ff&#34;&gt;0.2&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;8002&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We get the same sort of round-robin load balancing as the &lt;code&gt;pm2&lt;/code&gt; load balancing,but in a separate process. This allows us to restart individual instancesat will without downtime (e.g. &lt;code&gt;systemctl restart myapp@1&lt;/code&gt;), among otherniceties like TLS termination (see the linked &amp;ldquo;use a reverse proxy&amp;rdquo; articlefor a full example that includes TLS termination).&lt;/p&gt;&lt;h3 id=&#34;containerized-deployment&#34;&gt;  Containerized Deployment  &lt;a href=&#34;#containerized-deployment&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;But deploying in the bare metal manner described above is an increasinglyrare method of deploying applications. Nowadays most deployments are donethrough some form of &lt;a href=&#34;https://en.wikipedia.org/wiki/Containerization_(computing)&#34;&gt;containerization&lt;/a&gt;. The most basic of whichis &lt;a href=&#34;https://en.wikipedia.org/wiki/Docker_(software)&#34;&gt;Docker&lt;/a&gt;. In such a case, the container host acts as the processmanager and the &amp;ldquo;container&amp;rdquo; is the process. This means that the containershould be written such that the embedded application is booted directly:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-dockerfile&#34; data-lang=&#34;dockerfile&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; debian:stable-slim&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# copy script and node_modules into the container&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;PORT &lt;span style=&#34;color:#ae81ff&#34;&gt;8000&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CMD&lt;/span&gt; [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;node&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/myapp/index.js&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that we should use the same modified script as we used in the bare metaldeployment. The container host is still going to send traditional processmanagement signals and the application should recognize them.&lt;/p&gt;&lt;h2 id=&#34;conclusion&#34;&gt;  Conclusion  &lt;a href=&#34;#conclusion&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;pm2&lt;/code&gt; is a process manager that simplifies process management for developersthat may not have much knowledge of how systems manage processes. But it comeswith some inherent costs and caveats: namely it does not run applications inan unaltered environment. We should take care to deploy our applications withas little runtime environment changes as is necessary in order to reduce thenumber of things we need to investigate when something goes wrong. By utilizingthe standard tooling we are able to run our applications with as littleinterference as possible. And we also gain the benefit of anyone being able tomanage our applications through standard interfaces without having to learnnew setups and tools.&lt;/p&gt;</description>
     </item>
   
     <item>
       <title>Thoughts On JavaScript Classes</title>
       <link>https://jrfom.com/posts/2023/10/31/js-classes/</link>
       <pubDate>Tue, 31 Oct 2023 11:45:00 -0400</pubDate>
       
       <guid>https://jrfom.com/posts/2023/10/31/js-classes/</guid>
       <description>&lt;p&gt;Lately, the topic of JavaScript classes has come up in some open sourceprojects I participate in. In short, a contributor wants to convert existingprototype defined code to class defined code. I have mostly stayed out of theconversation as my primary position is one of the &lt;a href=&#34;https://knowyourmeme.com/memes/old-man-yells-at-cloud&#34;&gt;&amp;ldquo;old man yells at cloud&amp;rdquo;&lt;/a&gt;variety. But the primary counter argument is that &amp;ldquo;classes are easier tomaintain,&amp;rdquo; and I&amp;rsquo;d like to address that in this article.&lt;/p&gt;&lt;h2 id=&#34;background&#34;&gt;  Background  &lt;a href=&#34;#background&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;It should be well known by now that &lt;a href=&#34;https://web.archive.org/web/20230904145913/https://exploringjs.com/es6/ch_core-features.html#sec_from-constr-to-class&#34;&gt;es2015 introduced the &lt;code&gt;class&lt;/code&gt; syntax&lt;/a&gt;to JavaScript. I don&amp;rsquo;t want to rehash everything here, but for the context ofthis article, we will mainly concern ourselves with the difference between:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// A prototype defined object (&amp;#34;class&amp;#34;).&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Person&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;target&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Person&lt;/span&gt;(...&lt;span style=&#34;color:#a6e22e&#34;&gt;arguments&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;this&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;_name&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Person&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;prototype&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;sayName&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;stream&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;process&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;stdout&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;stream&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;write&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;this&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;_name&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// An es2015 class defined object.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Person&lt;/span&gt; {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;constructor&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;this&lt;/span&gt;.&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;sayName&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;stream&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;process&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;stdout&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;stream&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;write&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;this&lt;/span&gt;.&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;aside&gt;    For a full, up-to-date, discussion on what is available with the &lt;code&gt;class&lt;/code&gt; syntax,see &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes&#34;&gt;JavaScript Classes&lt;/a&gt;.&lt;/aside&gt;&lt;p&gt;Notice that in the prototype based instance we are utilizing a convention for&amp;ldquo;private&amp;rdquo; fields, prefixing the field name with an underscore, and in the classbased instance we are utilizing language defined syntax for the private field.&lt;/p&gt;&lt;h3 id=&#34;a-peek-behind-the-curtain&#34;&gt;  A Peek Behind The Curtain  &lt;a href=&#34;#a-peek-behind-the-curtain&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The line is getting fuzzier with each improvement to the class syntax, but wecan still see hints that the syntax is &lt;a href=&#34;https://en.wikipedia.org/wiki/Syntactic_sugar&#34;&gt;sugar&lt;/a&gt; on top of the prototype.Consider this alternate implementation of the &lt;code&gt;Person&lt;/code&gt; class:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Person&lt;/span&gt; {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;constructor&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;this&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Person&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;prototype&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;sayName&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;stream&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;process&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;stdout&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;stream&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;write&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;this&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So we are able to define the class with a minimum amount of code in the&lt;code&gt;class&lt;/code&gt; block, and extend it by adding to the prototype. Thus showing thatthe class is still a prototype based object after the syntax is interpreted.&lt;/p&gt;&lt;h2 id=&#34;which-is-more-maintainable&#34;&gt;  Which Is More Maintainable?  &lt;a href=&#34;#which-is-more-maintainable&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I think the context matters when considering this question. When I startedworking on the &lt;a href=&#34;https://github.com/ldapjs/node-ldapjs/releases/tag/v3.0.0&#34;&gt;v3.0.0 release of ldapjs&lt;/a&gt; I opted to rework theprototype defined objects into class defined objects:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;So that I could get familiar with the syntax.&lt;/li&gt;&lt;li&gt;It made sense considering the way the code was structured.&lt;/li&gt;&lt;li&gt;I wanted new contributors to be able to follow the code.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;I quickly encountered an issue that continues to frustrate me with the classsyntax: objects defined in this way really should have &lt;em&gt;all&lt;/em&gt; of the associatedcode written within the &lt;code&gt;class {}&lt;/code&gt; block. First, that&amp;rsquo;s what makes it legibleto programmers who are only familiar with class defined objects. And second,not all code &lt;em&gt;can&lt;/em&gt; be defined by extending the prototype.&lt;/p&gt;&lt;p&gt;Look closely at the two class defined objects in this article. In the first,we defined the &lt;code&gt;name&lt;/code&gt; field as a private field, and in the second as a publicfield. Let&amp;rsquo;s try combining the two:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Person&lt;/span&gt; {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;constructor&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;this&lt;/span&gt;.&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Person&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;prototype&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;sayName&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;stream&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;process&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;stdout&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;stream&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;write&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;this&lt;/span&gt;.&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When we try to include that definition in a script we will get a syntax error:&lt;/p&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;SyntaxError: Private field &amp;#39;#name&amp;#39; must be declared in an enclosing class&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In short, we lose access to private fields and methods when we try to extenda class through its prototype. So, if we have an object of any siginificantcomplexity, we cannot use this &amp;ldquo;trick&amp;rdquo; to break up our code into multiplescripts that would be easier to read and maintain unless we make all membersof the object public. Instead, we end up with a very large file that is, atleast to me, difficult to follow and find focus in. As example, see the&lt;a href=&#34;https://github.com/ldapjs/filter/blob/2f5fd6be88b26278536e18d02c4d6a3a4bb7425b/lib/filter-string.js&#34;&gt;base filter class&lt;/a&gt; that ended up in &lt;code&gt;ldapjs@3&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;If we want to retain the &amp;ldquo;private&amp;rdquo; nature of members along with being able toorganize our code into self-contained concerns, we can alter our prototypedefined object like so:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;symName&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Symbol&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;nameField&amp;#39;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Person&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;target&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Person&lt;/span&gt;(...&lt;span style=&#34;color:#a6e22e&#34;&gt;arguments&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;this&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;symName&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Person&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;prototype&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;sayName&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;stream&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;process&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;stdout&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;stream&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;write&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;this&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;symName&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We need to provide access to our symbols in any files we break code out into,but we retain our organizational flexibity along with strong hints to othersto keep away from the internals.&lt;/p&gt;&lt;h2 id=&#34;conclusion&#34;&gt;  Conclusion  &lt;a href=&#34;#conclusion&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I understand that more and more people are learning JavaScript from theperspective of solely using the class syntax, and that using it makes it easierfor them to understand the code. But I think that code organization is animportant factor in &amp;ldquo;maintainability.&amp;rdquo; I find that having to scroll up and downto remind myself of relevant sibling code is more difficult than having thetwo pieces opened side-by-side via different files. And I get just as lostas scrolling when trying to have the same file open in two panes whilepositioned to two different locations.&lt;/p&gt;&lt;p&gt;Ultimately, I think it&amp;rsquo;s probably best to write new code with class definedobjects specifically to have the widest reach for contributors. But I&amp;rsquo;mnot quite convinced it is such a big win that all code needs to be converted.It&amp;rsquo;d be easier for me to accept that outcome if we had the ability toorganize the code as described. I&amp;rsquo;m not sure I really like the way &lt;a href=&#34;https://go.dev/ref/spec#Source_file_organization&#34;&gt;Golang&lt;/a&gt;organizes packages, but it&amp;rsquo;s quite similar to what I&amp;rsquo;ve described here forprototype defined objects. Maybe there&amp;rsquo;s a way to &amp;ldquo;fix&amp;rdquo; the private memberaccess from non-block defined members in a future version of the language?&lt;/p&gt;</description>
     </item>
   
     <item>
       <title>Being A Human Among Other Humans</title>
       <link>https://jrfom.com/posts/2023/10/17/being-human-with-humans/</link>
       <pubDate>Tue, 17 Oct 2023 23:45:00 -0400</pubDate>
       
       <guid>https://jrfom.com/posts/2023/10/17/being-human-with-humans/</guid>
       <description>&lt;p&gt;This post is about my own mental image, and acceptance, of my physical self.There are nude images ahead, the most revaling of which are obscured behinda mouse click. I was inspired to write this after &lt;a href=&#34;https://www.instagram.com/p/CydsqnPuUbs/?igshid=NTc4MTIwNjQ2YQ%3D%3D&amp;amp;img_index=1&#34;&gt;a post&lt;/a&gt; by ayoga classmate from a yoga class that I started taking in the spring of thisyear (2023).&lt;/p&gt;&lt;div class=&#34;image-center&#34;&gt;          &lt;a href=&#34;https://jrfom.com/posts/2023/10/17/being-human-with-humans/insta_post.jpg&#34;&gt;      &lt;img        src=&#34;https://jrfom.com/posts/2023/10/17/being-human-with-humans/insta_post_huc82d7b839fc53b7a5c86bd3cdfedcac6_1337805_500x0_resize_q80_box.jpg&#34;        width=&#34;500&#34;        height=&#34;321&#34;        alt=&#34;Instagram post by @BreatheWithKay&#34;      /&gt;    &lt;/a&gt;  &lt;/div&gt;&lt;h2 id=&#34;my-fear&#34;&gt;  My Fear  &lt;a href=&#34;#my-fear&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;As a child, I played baseball and I remember being quite good at it. I believeI could have at least earned a scholorship if not gone a step or two further.But, I played until I reached the point where to continue would mean two things:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Having to get a physical.&lt;/li&gt;&lt;li&gt;Having to use a locker room with the rest of the team.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;In both cases, the blocker was a fear of being physically exposed in thepresence of other people. I don&amp;rsquo;t really know where this fear originated, butI&amp;rsquo;m sure a lot of it came from television or movies portraying body shamingas an acceptable fact of life in high school and beyond. Regardless of whereit originated, this trepidation has remained with me throughout my adult life.&lt;/p&gt;&lt;p&gt;It wasn&amp;rsquo;t until 2021, on the weekend of my 42nd birthday, that I really decidedto do something about it. It was then that I tried to participate in the&lt;a href=&#34;https://web.archive.org/web/20210702214920/https://philadelphianakedbikeride.wordpress.com/2021/03/22/pnbr-12-the-mask-edition-8-28-2021/&#34;&gt;2021 Philadelphia Naked Bike Ride&lt;/a&gt; (PNBR). I failed to do that due toa bad &lt;a href=&#34;https://jrfom.com/posts/2021/09/03/a-bike-crash/&#34;&gt;bike crash&lt;/a&gt; on my way to the gatheringspot. So I tried again with &lt;a href=&#34;https://web.archive.org/web/20230331030024/https://philadelphianakedbikeride.wordpress.com/2022/08/27/see-you-at-lemon-hill-starting-at-2-pm-we-ride-at-5-pm/&#34;&gt;PNBR 2022&lt;/a&gt; and was successful. It wasliberating. (Unfortunately, due to being out of work, I couldn&amp;rsquo;t attend in2023.)&lt;/p&gt;&lt;div class=&#34;image-center&#34;&gt;          &lt;a href=&#34;https://jrfom.com/posts/2023/10/17/being-human-with-humans/pnbr2022.jpeg&#34;&gt;      &lt;img        src=&#34;https://jrfom.com/posts/2023/10/17/being-human-with-humans/pnbr2022_hu244865fefffeb0606fb7334b598b9bec_4211558_0x400_resize_q80_box.jpeg&#34;        width=&#34;533&#34;        height=&#34;400&#34;        alt=&#34;Philadelphia Naked Bike Ride 2022 ride start&#34;      /&gt;    &lt;/a&gt;  &lt;/div&gt;&lt;h2 id=&#34;nude-yoga&#34;&gt;  Nude Yoga  &lt;a href=&#34;#nude-yoga&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;div class=&#34;image-right&#34;&gt;          &lt;a href=&#34;https://jrfom.com/posts/2023/10/17/being-human-with-humans/group_photo.jpeg&#34;&gt;      &lt;img        src=&#34;https://jrfom.com/posts/2023/10/17/being-human-with-humans/group_photo_hu523d093cb9d736a5a6528434fecd4a13_1139247_0x400_resize_q80_box.jpeg&#34;        width=&#34;300&#34;        height=&#34;400&#34;        alt=&#34;Group photo of yoga class&#34;      /&gt;    &lt;/a&gt;  &lt;/div&gt;The PNBR experience was liberating, at least in part, because it gave me anopportunity to be a human among other humans. My social skills are terrible.I had some success at university, but the vast majority of my adult life hasbeen one of solitude and extreme loneliness. What I learned during the PNBRexperience is that being naked with other people touches something that iscore to our being. Since experiencing that, I &lt;em&gt;had&lt;/em&gt; to find a way to get itclose to home, and I wanted the group aspect of it. So I turned to the otheractivity I practice regularly: yoga.&lt;/p&gt;&lt;style&gt;  .clear-both {    display: block;    clear: both;  }&lt;/style&gt;&lt;span class=&#34;clear-both&#34; /&gt;&lt;p&gt;I started by researching if nude yoga is even a thing. It is. There arepractices like &lt;a href=&#34;https://www.nakedinmotion.com&#34;&gt;Naked In Motion&lt;/a&gt;, &lt;a href=&#34;https://www.dharmahousecolumbus.com/nudeyoga&#34;&gt;Dharama House&lt;/a&gt;,&lt;a href=&#34;https://www.boldnaked.com&#34;&gt;Bold Naked&lt;/a&gt;, and others around the country. As an aside, see&lt;a href=&#34;https://www.thecut.com/2018/02/inside-a-naked-yoga-class-with-naked-in-motion.html&#34;&gt;this video article&lt;/a&gt; for a nice overview of Naked In Motionand &lt;a href=&#34;https://web.archive.org/web/20231018031723/https://people.com/food/we-tried-it-naked-yoga/&#34;&gt;this written article&lt;/a&gt; for a Bold Naked experience. I wouldcertainly like to try out any of these classes if I am able to get a chance.&lt;/p&gt;&lt;p&gt;What I found is that it is quite difficult to find anything in the Atlantaarea. There&amp;rsquo;s one that pops up at the top of search engine results, but it isn&amp;rsquo;ta class I would attend (it&amp;rsquo;s quite clear the class has extra curricularmotives). All of the others that are &amp;ldquo;easy&amp;rdquo; to find are either defunct orat least unresponsive to inquiries. So eventually I worked up the courage toask my regular instructor (shout out to &lt;a href=&#34;https://www.kimyb.com&#34;&gt;KIMYB&lt;/a&gt;), that I have been takingclasses from since February of 2019, if she knew of any. She didn&amp;rsquo;t evenhave to think about it. She was able to point me in the direction of&lt;a href=&#34;https://www.theyogaplayground.com&#34;&gt;The Yoga Playground&lt;/a&gt; and it has been amazing.&lt;/p&gt;&lt;p&gt;Eazy&amp;rsquo;s class is exactly what I was looking for: a co-ed class that is all aboutbeing comfortable with oneself and sharing the experience with others. Justbeing in the room allows me to make that base connection, even if my actualsocial skills are still poor. But that&amp;rsquo;s another benefit: I actually feelit&amp;rsquo;s easier to talk to others when we are exposed like that, and I&amp;rsquo;m gettingbetter at striking up conversations before and after class.&lt;/p&gt;&lt;p&gt;It&amp;rsquo;s still intimidating to bare it all at the start of every class. I&amp;rsquo;m alwaysquestioning if I&amp;rsquo;m doing the right thing by, usually, being the first to getrid of the shields and storing them with my gear bag in the foyer. But I tellmyself &amp;ldquo;we&amp;rsquo;re here for a reason, so let&amp;rsquo;s do it.&amp;rdquo; But by the end of class,particularly on the nights when folks chill and socialize for a bit afterward,that trepidation is gone. I look forward to each and every class. They filla void in my life.&lt;/p&gt;&lt;div class=&#34;spoiler&#34;&gt;  &lt;input id=&#34;spoiler-faa3ea3&#34; type=&#34;checkbox&#34;&gt;          &lt;img      class=&#34;spoiler-filtered&#34;      src=&#34;https://jrfom.com/posts/2023/10/17/being-human-with-humans/me_hu0d7ff8b3e3ea4d50f07feb7bd0477d82_2202552_0x600_resize_q80_box.jpeg&#34;      width=&#34;450&#34;      height=&#34;600&#34;      alt=&#34;Me doing a headstand (NSFW)&#34;    /&gt;    &lt;label for=&#34;spoiler-faa3ea3&#34; class=&#34;spoiler-button&#34;&gt;      Me doing a headstand (NSFW)    &lt;/label&gt;    &lt;a class=&#34;spoiler-original&#34; href=&#34;https://jrfom.com/posts/2023/10/17/being-human-with-humans/me.jpeg&#34;&gt;      &lt;img        src=&#34;https://jrfom.com/posts/2023/10/17/being-human-with-humans/me_hu0d7ff8b3e3ea4d50f07feb7bd0477d82_2202552_0x600_resize_q80_box.jpeg&#34;        width=&#34;450&#34;        height=&#34;600&#34;        alt=&#34;Me doing a headstand (NSFW)&#34;      /&gt;    &lt;/a&gt;  &lt;/div&gt;&lt;h2 id=&#34;conclusion&#34;&gt;  Conclusion  &lt;a href=&#34;#conclusion&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This has been a bit of a ramble, but I felt that I should get at least someof it out there. I don&amp;rsquo;t know if it will help anyone else to overcome theirown insecurities, or if I&amp;rsquo;m just exposing more of myself for the helluva it,but this is the Room Full of Mirrors.&lt;/p&gt;</description>
     </item>
   
     <item>
       <title>Soverin Plus SimpleLogin</title>
       <link>https://jrfom.com/posts/2023/03/29/soverin-plus-simplelogin/</link>
       <pubDate>Wed, 29 Mar 2023 10:30:00 -0400</pubDate>
       
       <guid>https://jrfom.com/posts/2023/03/29/soverin-plus-simplelogin/</guid>
       <description>&lt;p&gt;I used to run my own email server for several years before I switched over to using Gmail. It was nice having my own domain, but maintaining the server and dealing with flaky internet services eventually became too much. So I have been using Gmail as my primary email service since 2004-08-19. But in late August of 2019 I finally got tired of dealing with all of the advertisements in my inbox. I get a &lt;em&gt;lot&lt;/em&gt; of email, and dismissing advertisements before getting into dismissing all of the email is really tiresome.&lt;/p&gt;&lt;p&gt;Enter &lt;a href=&#34;https://soverin.net&#34;&gt;Soverin.net&lt;/a&gt;.&lt;/p&gt;&lt;h2 id=&#34;soverin&#34;&gt;  Soverin  &lt;a href=&#34;#soverin&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Soverin is a traditional email provider that:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Uses TLS for receive and send by default&lt;/li&gt;&lt;li&gt;Supports IMAP&lt;/li&gt;&lt;li&gt;Supports custom domains&lt;/li&gt;&lt;li&gt;Provides an anonymous email address&lt;/li&gt;&lt;li&gt;Email address aliases&lt;/li&gt;&lt;li&gt;Supports server-side filtering&lt;/li&gt;&lt;li&gt;Supports configurable spam protection&lt;/li&gt;&lt;li&gt;Provides a usable webmail interface&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;For the most part, the service is just plain email and doesn&amp;rsquo;t need any explanation. But there are a few features that I think deserve some dedicated discussion: the anonymous email address, server-side filtering, and email aliases.&lt;/p&gt;&lt;p&gt;Let&amp;rsquo;s cover the server-side filtering first. This is a familiar feature from Gmail, and other webmail services. It allows you to define rules that incoming emails will be matched against. The matched emails will have some sort of action performed, e.g. moving the email to an IMAP &amp;ldquo;folder&amp;rdquo;.  Maybe things have changed since I was running my own server, or I just didn&amp;rsquo;t know enough 🤷‍♂️, but a little bit of research shows that servers like Exim support user and system filter files that provide this sort of functionality. But maintaining such files are yet another chore in maintaining the email server. Soverin provides a nice web interface that makes it easy.&lt;/p&gt;&lt;p&gt;Additionally, they support some filtering that doesn&amp;rsquo;t require any configuration. Specifically, they have added filtering to plus addresses (subaddressing). For example, if your IMAP has a folder named &lt;strong&gt;foo&lt;/strong&gt;, and your Soverin email address is &lt;code&gt;email@example.com&lt;/code&gt;, then emails delivered to &lt;code&gt;email+foo@example.com&lt;/code&gt; will be automatically delivered to that &lt;strong&gt;foo&lt;/strong&gt; IMAP folder. This is a nice extension to the subaddressing popularized by Gmail.&lt;/p&gt;&lt;p&gt;Next is the very unique feature of an anonymous email address provided to each mailbox. This is an address that bears no visible relationship to your actual email address, but will deliver emails sent to it to your mailbox, and can be used to hide your information when sending emails. This was a pretty cool feature to discover upon signing up, because it isn&amp;rsquo;t advertised anywhere on their site. It&amp;rsquo;s really nice being able to hide your real details from some sketchy sites.&lt;/p&gt;&lt;p&gt;And finally, email address aliases are supported at the domain and mailbox levels. As an example, if &lt;code&gt;email@example.com&lt;/code&gt; is your primary address, and you need to create a new account with some website named &lt;strong&gt;megastore&lt;/strong&gt;. You can create an alias &lt;code&gt;megastore@example.com&lt;/code&gt; and any emails sent to it will be delivered to the &lt;code&gt;email@example.com&lt;/code&gt; mailbox. Additionally, every mailbox supports a catch-all option that can be set to either reject unrecognized emails or deliver them to the mailbox. Which means you can create arbitrary aliases any time without having to go to your Soverin dashboard: merely give out an alias-like address and it will be delivered accordingly by setting the catch-all to accept instead of reject.&lt;/p&gt;&lt;h2 id=&#34;simplelogin&#34;&gt;  SimpleLogin  &lt;a href=&#34;#simplelogin&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;There is a problem with aliases and catch-all delivery, though: sending emails from an alias address is impossible without first adding that alias to your Soverin account through the dashboard. In other words, if &lt;code&gt;foo@example.com&lt;/code&gt; is an alias added in the dashboard and &lt;code&gt;bar@example.com&lt;/code&gt; is an alias managed through the catch-all feature, &lt;em&gt;&lt;strong&gt;only&lt;/strong&gt;&lt;/em&gt; the &lt;code&gt;foo@example.com&lt;/code&gt; address can be used to send outgoing emails. This makes it really cumbersome to manage aliases and keep your main details hidden. That is, the purpose, for me, in using email aliases is to hand out email address I can easily tie to companies and see who has decided to sell my information. But I still want to be able to communicate with these companies without exposing the address I was trying to hide in the first place.&lt;/p&gt;&lt;p&gt;This is where &lt;a href=&#34;https://simplelogin.io&#34;&gt;SimpleLogin&lt;/a&gt; (SL) comes in. Basically, SL takes the catch-all + alias feature and turns it into a usable product. SL will receive emails, rewrite the reply-to headers to point back to SL, and then deliver the email to an email address you have specified. Further, SL supports adding &lt;em&gt;outgoing&lt;/em&gt; aliases to an email address. And at any time, you can log in to your SL dashboard and disable an alias, thus stopping any emails sent to it from ever getting to your inbox. This is really powerful, and I have two examples to show it.&lt;/p&gt;&lt;h3 id=&#34;dealing-with-a-businesses&#34;&gt;  Dealing With A Businesses  &lt;a href=&#34;#dealing-with-a-businesses&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Mentioned above is the scenario where you need to give a business an email address, but you don&amp;rsquo;t want to give out your &lt;em&gt;actual&lt;/em&gt; address. This is easy with SL. Assuming you have SL configured to recognize emails sent to the domain &lt;code&gt;example.net&lt;/code&gt;, and the business name is &lt;code&gt;SketchyRUs&lt;/code&gt;, you simply give the business the email address &lt;code&gt;sketchyrus@example.net&lt;/code&gt; and their emails will be remapped and forwarded your primary address, e.g. &lt;code&gt;me@example.com&lt;/code&gt;. Now, any email you get from &lt;code&gt;sketchyrus@example.net&lt;/code&gt; can simply be replied to and it will go to the right people without your private address being revealed.&lt;/p&gt;&lt;p&gt;That&amp;rsquo;s the basic case. Now let&amp;rsquo;s assume you have encountered some situation where you need to initiate contact with the company. Maybe the product you bought from them is defective and you need to start a conversation with their support department and their email is &lt;code&gt;support@sketchrus.com&lt;/code&gt;. First, login to your SL dashboard, find the &lt;code&gt;sketchyrus@example.net&lt;/code&gt; address, click the &amp;ldquo;Contacts&amp;rdquo; button, and add a new &amp;ldquo;reverse-alias&amp;rdquo; for &lt;code&gt;support@sketchyrus.com&lt;/code&gt;. This will create a new email address that you can copy and use in an outgoing email.&lt;/p&gt;&lt;p&gt;So let&amp;rsquo;s say that SL generated &lt;code&gt;abc123def@simplelogin.co&lt;/code&gt; as the reverse alias. When you send an email to this address, SL will rewrite all of the outgoing headers to look like they are coming from the SL service and your &lt;code&gt;sketchyrus@example.net&lt;/code&gt; alias. When the support team responds, their email will go to SL, who will then rewrite the headers for that email and deliever it to your inbox.&lt;/p&gt;&lt;p&gt;And just like that, 💥, you get to hide your real email address while still being able to easily communicate with are remote service. This also solves another problem with Soverin native aliases: you don&amp;rsquo;t have to configure your email client with a new profile in order to send emails from the alias. Now, all that is required is copying the outgoing reverse alias whenever you need it, or simply adding that reverse alias to your email client&amp;rsquo;s address book.&lt;/p&gt;&lt;p&gt;A real-world example of how this setup is beneficial occurred for me in February. I had a coupon for an oil change at a car dealership that I had not dealt with before. When I made the appointment I used an email address like &lt;code&gt;car.dealership@example.com&lt;/code&gt;. The appointment came and went. A few days later, I started getting emails from SiriusXM addressed to the email I gave the car dealership. I knew right away who had sold my information, and I was able to stop the emails without giving them &lt;em&gt;any&lt;/em&gt; interaction: I just logged in to SL and turned off that alias.&lt;/p&gt;&lt;h3 id=&#34;mailing-list-subscriptions&#34;&gt;  Mailing List Subscriptions  &lt;a href=&#34;#mailing-list-subscriptions&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Another great use case for SL is signing up for mailing lists. I have been a member of the &lt;a href=&#34;https://ale.org&#34;&gt;Atlanta Linux Enthusiasts&lt;/a&gt; (ALE) mailing list for a couple of decades. Like most public mailing lists of this nature, there is a public archive all of all the emails sent to it. These archived emails include the full sender details; that is, the email address you use to interact with the mailing list is not private.&lt;/p&gt;&lt;p&gt;Using SL, we can fix this problem. It&amp;rsquo;s really the same thing as the previously discussed business scenario:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Sign-up to the mailing list with your alias, e.g. &lt;code&gt;ale@example.com&lt;/code&gt; (where &lt;code&gt;example.com&lt;/code&gt; is the domain you use for alias addresses)&lt;/li&gt;&lt;li&gt;Create a reverse alias via the SL dashboard&lt;/li&gt;&lt;li&gt;Add the reverse alias to your address book&lt;/li&gt;&lt;li&gt;Reply to emails from the mailing list without doing anything special, and start new threads by sending an email to the reverse alias stored in your address book&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;There is one thing, however, that can set this scenario apart from the business scenario: Soverin&amp;rsquo;s server-side filtering! All of the emails you get from the mailing list will have some sort of distinguishing feature that can be used to route those emails into a specific IMAP folder. In ALE case, the &lt;code&gt;From:&lt;/code&gt; header will always have &lt;code&gt;ale@ale.org&lt;/code&gt; in the value. So all we have to do is create a filter that inspect that header for that value and configure it to move those emails to a unique folder. We never have to configure anything in our email client for dealing with these emails 😀.&lt;/p&gt;&lt;h2 id=&#34;summary&#34;&gt;  Summary  &lt;a href=&#34;#summary&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Soverin in combination with SimpleLogin is a really powerful setup for managing your own email. You can rely one or both of their domains, or you can provide each with unique domains. You can setup a subdomain to give to SL for aliases, if you only want to deal with one &lt;a href=&#34;https://en.wikipedia.org/wiki/Top-level_domain&#34;&gt;TLD&lt;/a&gt;. Personally, I have one TLD for Soverin and another &lt;code&gt;.com&lt;/code&gt; that I use for my aliases. &lt;a href=&#34;https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail&#34;&gt;DKIM&lt;/a&gt; and &lt;a href=&#34;https://en.wikipedia.org/wiki/Sender_Policy_Framework&#34;&gt;SPF&lt;/a&gt; is supported throughout.&lt;/p&gt;&lt;p&gt;I&amp;rsquo;d love to see Soverin integrate SL directly so that I can reduce my costs, but SL is quite affordable and the dashboard is very clean. It&amp;rsquo;s a great service on its own, and will pair nicely with any email provider, including Gmail.&lt;/p&gt;&lt;p&gt;I highly recommend Soverin if you want a traditional email host with some nice extras. And I definitely recommend SimpleLogin to anyone that cares about keeping their inbox even a little bit private and manageable.&lt;/p&gt;</description>
     </item>
   
     <item>
       <title>Using A Unifi UDM-PRO At Home</title>
       <link>https://jrfom.com/posts/2022/09/29/unifi-udm-pro-at-home/</link>
       <pubDate>Thu, 29 Sep 2022 17:30:00 -0400</pubDate>
       
       <guid>https://jrfom.com/posts/2022/09/29/unifi-udm-pro-at-home/</guid>
       <description>&lt;p&gt;In August of 2017 I acquired my first &lt;a href=&#34;https://ui.com/&#34;&gt;Unifi&lt;/a&gt; gear: an 8 port 60W PoEswitch, and the UAP-AC-PRO wireless access point. I paired them with a box Ibuilt that was running &lt;a href=&#34;https://www.pfsense.org&#34;&gt;pfSense&lt;/a&gt;, and was able to setup VLANs for myregular network traffic and Internet of Things (IoT) traffic. This workedgreat. I was able to use &lt;a href=&#34;https://en.wikipedia.org/wiki/VnStat&#34;&gt;vnStat&lt;/a&gt; to keep track of my monthly datausage (since I refused to pay Comcast their extortion fee to get an uncappedconnection), and generally do everything I needed.&lt;/p&gt;&lt;p&gt;Fast forward to March 2021 and some &lt;a href=&#34;https://web.archive.org/web/20220903111305/https://arstechnica.com/gadgets/2021/03/buffer-overruns-license-violations-and-bad-code-freebsd-13s-close-call/&#34;&gt;shenanigans&lt;/a&gt; with pfSense,FreeBSD, and WireGuard made me want to get off of pfSense and at least moveto &lt;a href=&#34;https://opnsense.org&#34;&gt;OPNsense&lt;/a&gt;. But that would be a lot of work, and I kept puttingit off. I considered switching to the Unifi &lt;a href=&#34;https://store.ui.com/products/udm-pro&#34;&gt;UDM-PRO&lt;/a&gt; at the timeas well, but the folks at Ubiquiti can&amp;rsquo;t seem to grasp the concept of vnStatand why anyone would need it. So it was off the table&amp;hellip;&lt;/p&gt;&lt;p&gt;Until my previous employer started paying a $100/mo ISP stipend. I kept runningup against Comcast&amp;rsquo;s stupid cap, so I decided to use the stipend to pay myregular ISP bill plus their extortion fee. So the need to track my data usagewas removed, but it was still going to be a lot of work to switch from my ownrouter/gateway to the UDM-PRO, and so I kept putting it off&amp;hellip;&lt;/p&gt;&lt;p&gt;Until in late July of this year my pfSense box started acting up. It was clearthe hardware was reaching its limit so I needed to at least perform a rebuild.I decided that this would be my opportunity to switch to the UDM-PRO, and thisarticle is about the work I have had to do to get it into a state approximatingwhat I had with off-the-shelf components and a free operating system.&lt;/p&gt;&lt;h2 id=&#34;prosumer-but-lacking&#34;&gt;  Prosumer But Lacking  &lt;a href=&#34;#prosumer-but-lacking&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I like the Unifi gear because there isn&amp;rsquo;t any other &amp;ldquo;prosumer&amp;rdquo; gear out therethat provides an &lt;a href=&#34;https://en.wikipedia.org/wiki/Software-defined_networking&#34;&gt;SDN&lt;/a&gt; ecosystem that even remotely compares. In general,the Unifi stuff &amp;ldquo;just works&amp;rdquo; and has a good interface for configuring it. Thatremains true of the UDM-PRO. Switching to it was basically:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Pull out the old box&lt;/li&gt;&lt;li&gt;Put in the new gateway&lt;/li&gt;&lt;li&gt;Add ISP credentials&lt;/li&gt;&lt;li&gt;Reconfigure VLANs to not be tagged only (since pfSense was managing them before)&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;But what I lost was:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;A local domain with split authoritative and recursive DNS lookup:&lt;ul&gt;&lt;li&gt;In short, I have a domain that I consider my &amp;ldquo;home domain&amp;rdquo;. In other words,all of my devices name themselves within it and it serves as an address toreach my home network. pfSense would automatically register devices underthis domain, serve out DNS entries for them, and issue a recursive lookupfor any queries that didn&amp;rsquo;t match the local authoritative database. TheUDM-PRO uses the exact same tool for the local DNS proxy that pfSense uses,but totally ignores this scenario.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Easy management of DHCP&lt;ul&gt;&lt;li&gt;pfSense had a central DHCP configuration panel, with sections for eachsubnet. This made it really easy to configure each subnet, and to configure&amp;ldquo;static&amp;rdquo; addresses for specific clients. With the UDM-PRO, you have tonavigate to each device and dig through a properties menu to add a staticaddress for it. You also do not get a simple overview of all the DHCPconfiguration and reserved addresses.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Easy on-gateway tooling to inspect and diagnose the ISP connection&lt;ul&gt;&lt;li&gt;With pfSense it was very easy to see the ISP assigned IP addresses and theassigned nameservers. The only thing the UDM-PRO shows is the IPv4 ISPassigned address. And pfSense included a web UI for tools like &lt;code&gt;ping&lt;/code&gt; or&lt;code&gt;traceroute&lt;/code&gt; to easily diagnose problems from the gateway. The UDM-PRO doesn&amp;rsquo;tprovide anything of this sort.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Easy dynamic DNS management&lt;ul&gt;&lt;li&gt;Supposedly the UDM-PRO works with various dynamic DNS services, includingthe one I used, afraid.org, but the configuration tool is extremely barebones and completely undocumented. I could never figure out how to use itcorrectly, and gave up on it.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=&#34;dns&#34;&gt;  DNS  &lt;a href=&#34;#dns&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I need to expand on the DNS problem above. It&amp;rsquo;s really bad. It doesn&amp;rsquo;t take muchsearching to find many people complaining about the whole of the time theUDM-PRO has been in existence. I understand Ubiquiti&amp;rsquo;s perspective: the deviceis really meant to be a gateway in a small office or enterprise. As such, theyexpect you&amp;rsquo;d have your own servers providing this service. But even in thatscenario, their competition is literally pfSense/OPNsense. And, as I haveshown, this is a very easy included feature in those products. Ubiquiti needsto wake up and start listening to their customers (and this is just one caseof several in which that statement holds).&lt;/p&gt;&lt;p&gt;Initially, I attempted to solve this problem for myself by building a&lt;a href=&#34;https://en.wikipedia.org/wiki/Docker_(software)&#34;&gt;Docker&lt;/a&gt; service to provide the DNS setup I described above. It&amp;rsquo;savailable at &lt;a href=&#34;https://github.com/jsumners/udm-dns&#34;&gt;https://github.com/jsumners/udm-dns&lt;/a&gt;. But after getting that setupI discovered a complication: I run a dual-stack IPv4 and IPv6 network. Theissue there is that most operating systems and devices, in particular macOS,search for IPv6 DNS entries first. Since that &lt;code&gt;udm-dns&lt;/code&gt; project can only provideIPv4 DNS (easily), I was left with slow and outright failing DNS lookups afterconfiguring the UDM-PRO to assign clients a primary nameserver pointing tothat service.&lt;/p&gt;&lt;p&gt;So I had to temporarily disable it.&lt;/p&gt;&lt;h2 id=&#34;fixing-my-problems&#34;&gt;  Fixing My Problems  &lt;a href=&#34;#fixing-my-problems&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Most people go about fixing these sort of problems by installing servicesdirectly on their UDM-PRO. The software features of the device are built uponDocker ([podman][podman]), and it has some fairly capable hardware specs. ButI haven&amp;rsquo;t done that. I don&amp;rsquo;t want to risk my changes being lost in a deviceupgrade, and I&amp;rsquo;d rather the gateway devote all of its resources to the thingsit is purports to support.&lt;/p&gt;&lt;p&gt;Instead, I bought an &lt;a href=&#34;https://www.amazon.com/HP-EliteDesk-800-triple-level-Bluetooth/dp/B01N3AL7TC&#34;&gt;HP EliteDesk 800 G3&lt;/a&gt; for a couple hundred bucks atmy local Microcenter to serve as a home server until I am ready to buy somevariant/build of a &lt;a href=&#34;https://www.amazon.com/Supermicro-Mount-Server-Chassis-CSE-505-203B/dp/B0093HNUD0&#34;&gt;Supermicro&lt;/a&gt; that will actually fit in my rack.Over the past two months, as time and desire has permitted, I have been buildingup this home server to fill in all of the gaps that the UDM-PRO has. The resultis &lt;a href=&#34;https://github.com/jsumners/home-server&#34;&gt;https://github.com/jsumners/home-server&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;That project:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Provides local authoritative + recursive DNS on both IPv4 and IPv6. The IPv6support is handled through usage of a &lt;a href=&#34;https://en.wikipedia.org/wiki/Unique_local_address&#34;&gt;ULA network&lt;/a&gt; so that I can manuallyassign easy to remember static addresses (mainly just the home server&amp;rsquo;sinterface) and let other devices pick up automatic addresses through routeradvertisement. This DNS server also picks up any clients connected to mynetwork by querying the UDM-PRO to get their addresses and names via&lt;a href=&#34;https://github.com/jsumners/udm-pro-api-client&#34;&gt;https://github.com/jsumners/udm-pro-api-client&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Removes the need for afraid.org and updates whatever dynamic domains I wantdirectly with my registrar through &lt;a href=&#34;https://github.com/jsumners/gandi-dyndns&#34;&gt;https://github.com/jsumners/gandi-dyndns&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Provides a local TLS terminating proxy that I can use for all of my internalservices and any that I care to expose publicly.&lt;/li&gt;&lt;li&gt;Backs up any events recorded by the &lt;a href=&#34;https://store.ui.com/collections/unifi-protect/products/uvc-g4-pro&#34;&gt;Unifi G4 camera&lt;/a&gt; I added tothe system. Yet another failing by Ubiquiti. It should be very obvious toanyone that recordings need to be backed up offsite as quickly as possible.But the UDM-PRO doesn&amp;rsquo;t offer that functionality, and it had to be patched inwith &lt;a href=&#34;https://github.com/ep1cman/unifi-protect-backup&#34;&gt;https://github.com/ep1cman/unifi-protect-backup&lt;/a&gt; (which is authored bya very helpful developer and provides way more functionality than I&amp;rsquo;m sureUbiquiti ever will if they wake up and implement anything).&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=&#34;summary&#34;&gt;  Summary  &lt;a href=&#34;#summary&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I genuinely like the Unifi gear. But I really wish Ubiquiti had some realcompetition to make their products better. This project was really not one Iwanted to take on. But hopefully others can get a head start from my work ifthey decide to build out on the Unifi line with the UDM-PRO as their centerpiece.&lt;/p&gt;</description>
     </item>
   
     <item>
       <title>Wahoo Elemnt Bolt vs Garmin Edge 1040</title>
       <link>https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/</link>
       <pubDate>Mon, 04 Jul 2022 16:30:00 -0400</pubDate>
       
       <guid>https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/</guid>
       <description>&lt;p&gt;This article is for the people using the &lt;a href=&#34;https://web.archive.org/web/20220331003006/https://www.wahoofitness.com/devices/bike-computers/elemnt-bolt&#34;&gt;Wahoo Bolt v2&lt;/a&gt; and consideringthe &lt;a href=&#34;https://web.archive.org/web/20220702104012/https://www.garmin.com/en-US/p/731136&#34;&gt;Garmin Edge 1040&lt;/a&gt;. This is not a long term review of either unit;for that see &lt;a href=&#34;https://www.dcrainmaker.com&#34;&gt;DC Rainmaker&amp;rsquo;s&lt;/a&gt; reviews: &lt;a href=&#34;https://web.archive.org/web/20220505134126/https://www.dcrainmaker.com/2021/05/wahoo-elemnt-bolt-v2-2021-with-color-screen-maps-a-review-in-progress.html&#34;&gt;Boltv2&lt;/a&gt; and &lt;a href=&#34;https://web.archive.org/web/20220608172335/https://www.dcrainmaker.com/2022/06/garmin-edge-1040-with-solar-in-depth-review.html&#34;&gt;Edge 1040&lt;/a&gt;. The short summary is: the Edge1040 is a better computer all around, and definitely worth it for people whowant to actually train.&lt;/p&gt;&lt;h2 id=&#34;wahoo-bolt-v2&#34;&gt;  Wahoo Bolt (v2)  &lt;a href=&#34;#wahoo-bolt-v2&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I already have a few thoughts jotted down in my post on&lt;a href=&#34;https://jrfom.com/posts/2021/10/19/wahoo-thoughts/&#34;&gt;Wahoo products&lt;/a&gt; in general. To summarize thosethoughts: I want to support a local Atlanta business, I like their approachto things, but there are a lot of rough edges. It&amp;rsquo;s those rough edges thatcaused me to change computers and write this post.&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://www.strava.com/activities/7404339550&#34;&gt;Saturday, July 2, 2022&lt;/a&gt; was thelast time I used this computer. At my 60 mile rest stop, I was fed up enoughthat I ordered the Edge 1040 before I got back on my bike. It seems like everynew firmware the device gets worse and worse. For a long time, it was readingthe ambient temperature wildly wrong; some recent firmware seems to havefixed that one. On Saturday, the things that got me upset were:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;It takes literal minutes for the computer to pick up my devices at thestart of a ride. In particular, it takes a long time for my &lt;a href=&#34;https://web.archive.org/web/20220404111255/https://www.garmin.com/en-US/p/658594&#34;&gt;Rally XC200&lt;/a&gt;pedals to be found. Once found, it&amp;rsquo;s a lottery to see if the computer willactually zero them; usually taking two or three tries.&lt;/li&gt;&lt;li&gt;The instant velocity readings were all over the place. It&amp;rsquo;d read 11mph andthen 30mph in the span of a few feet. It has become impossible to rely on thething to know how fast I&amp;rsquo;m traveling at any point in time. The only accuratereading is at the end when the miles are divided by total ride time.&lt;/li&gt;&lt;li&gt;Some point between mile 40 and mile 60 the computer auto-paused for severalseconds while I was traveling at least 15 to 20mph. This was the last straw.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Yes, I was on the latest firmware: WA39-14983. Point 1 has been an issue formonths, and the pedal syncing has been the case since day one with the pedals.Point 2 is a recent development, but present over several firmware versions.I am sure point 3 is tied to point 2, but I don&amp;rsquo;t care.&lt;/p&gt;&lt;h3 id=&#34;the-good-parts&#34;&gt;  The Good Parts  &lt;a href=&#34;#the-good-parts&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;All of that said, I really like the Bolt computer. I don&amp;rsquo;t need a lot out of abike computer. I mainly use them to keep track of basic stats so that I cansee my improvement over time. I do not ride regimented training plans, becauseI do not particpate in races; I&amp;rsquo;m just out to keep fit and have fun.&lt;/p&gt;&lt;p&gt;The Bolt is a simple, focused, computer that is very easy to use. The thingsI like about it over the Edge 1040 are:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The screen: there&amp;rsquo;s no question that the Bolt&amp;rsquo;s screen is better. It&amp;rsquo;s fareasier to read in direct sunglight and scattered sunlight (overhead treecanopy).&lt;/li&gt;&lt;li&gt;The coloring of fields to indicate difficulty/work zone. In particular, theelevation gradient, heart rate, and power meter fields.&lt;/li&gt;&lt;li&gt;Easy to use buttons.&lt;/li&gt;&lt;li&gt;The start/pause feature is way easier to work with.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The gallery below shows the primary pages I use on the Bolt, the features Idescribe above, and what a post ride summary on the device looks like.&lt;/p&gt;                &lt;style&gt;      .image-gallery {        display: grid;        grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));        gap: 0.5em;      }    &lt;/style&gt;    &lt;div class=&#34;image-gallery&#34;&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;bolt/IMG_3388.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/bolt/IMG_3388_huffeb95fbf79910c405b5f0d415f08f9d_2841329_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;bolt/IMG_3389.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/bolt/IMG_3389_huffeb95fbf79910c405b5f0d415f08f9d_2746363_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;bolt/IMG_3390.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/bolt/IMG_3390_huffeb95fbf79910c405b5f0d415f08f9d_2823002_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;bolt/IMG_3391.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/bolt/IMG_3391_huffeb95fbf79910c405b5f0d415f08f9d_2869765_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;bolt/IMG_3393.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/bolt/IMG_3393_huffeb95fbf79910c405b5f0d415f08f9d_2779693_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;bolt/IMG_3394.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/bolt/IMG_3394_huffeb95fbf79910c405b5f0d415f08f9d_2770102_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;bolt/IMG_3395.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/bolt/IMG_3395_huffeb95fbf79910c405b5f0d415f08f9d_2724046_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;bolt/IMG_3396.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/bolt/IMG_3396_huffeb95fbf79910c405b5f0d415f08f9d_2776013_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;bolt/IMG_3397.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/bolt/IMG_3397_huffeb95fbf79910c405b5f0d415f08f9d_2719625_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;bolt/IMG_3398.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/bolt/IMG_3398_huffeb95fbf79910c405b5f0d415f08f9d_2777705_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;      &lt;/div&gt;&lt;h2 id=&#34;garmin-edge-1040-solar&#34;&gt;  Garmin Edge 1040 (Solar)  &lt;a href=&#34;#garmin-edge-1040-solar&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;First off, bear in mind that I have used this computer for a total of one ride.Again, this is not a long term review. It&amp;rsquo;s my impressions as someone movingfrom one ecosystem to the other; I have never used any bike computer otherthan the Wahoo Bolt series prior to this Garmin computer. That said:&lt;/p&gt;&lt;p&gt;Wow. This computer is in a different league. It is clear to me that the Edge1040 is the computer to get, between the two, if you are someone that is lookingfor a computer to train with. All of its features are geared to the seriousathlete that is riding specific training plans.&lt;/p&gt;&lt;p&gt;I was able to replicate my main primary screen from the Bolt, and the screenwhere I can see my power and left-right balance information, but too many fieldswere lacking to recreate the other pages. That, or I could not get the Edgeto use the correct field. For example, I should be able to recreate my elevationpage, but the Edge refuses to put the graph in place and instead shows thecurrent elevation, e.g. 4,000ft. The built-in elevation page is a pretty goodsubstitute, it just doesn&amp;rsquo;t have the current 3s power field that I like to have.&lt;/p&gt;&lt;p&gt;The lack of fields doesn&amp;rsquo;t seem to be a limitation of the device, though. Itseems to be a limitation of the firmware. I may write Garmin to ask for themissing fields, e.g. &amp;ldquo;max heart rate&amp;rdquo; and &amp;ldquo;avg heart rate&amp;rdquo;. But if they don&amp;rsquo;tadd them, there is the &lt;a href=&#34;https://developer.garmin.com/connect-iq/sdk/&#34;&gt;Connect IQ SDK&lt;/a&gt;. While I really don&amp;rsquo;t want to haveto write my own code to get stuff on the computer, it&amp;rsquo;s &lt;em&gt;very&lt;/em&gt; nice to havethe option. There is not even the hint of an SDK available for the Wahoo Bolt.And there are a few apps in the Connect IQ store that look pretty good and showthat there is a lot more functionality possible.&lt;/p&gt;&lt;p&gt;The parts I like about the Edge 1040 are:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;It&amp;rsquo;s fast. Way, &lt;em&gt;way&lt;/em&gt;, faster than the Bolt. It powers on to the home screenin under 12 seconds. The Bolt takes about 38 seconds.&lt;/li&gt;&lt;li&gt;Over my &lt;a href=&#34;https://www.strava.com/activities/7414078946&#34;&gt;40 mile ride&lt;/a&gt; withthe computer, it used about 4% battery. Really not bad. I think the Bolt usesabout the same, maybe a few percent more over the same ride.&lt;/li&gt;&lt;li&gt;&lt;em&gt;All&lt;/em&gt; of my sensors pair up in about 2 total seconds. A significantimprovement over the minute or more on the Bolt.&lt;/li&gt;&lt;li&gt;Really good integration with the Varia Radar and Rally XC200 pedals. Yes,that &lt;em&gt;should&lt;/em&gt; be the case since they are all made by the same manufacturer, butit&amp;rsquo;s still very nice to have on computer control of things like what mode thelight is in. I don&amp;rsquo;t really fault Wahoo here; but maybe I would if I were todig in to the ANT+ protocol and see if Garmin is keeping things from Wahoo orif Wahoo is ignoring available features. Can&amp;rsquo;t say.&lt;/li&gt;&lt;li&gt;Strava segements support is actually useful instead of completely annoying.Whereas the Bolt, if I remember correctly, takes over the screen for everysegment you come across, the Edge only does that for short segments and it&lt;em&gt;only&lt;/em&gt; tracks segments you have starred in Strava. On the longer, multiplemile, segments, the Edge just gives a report at the end and leaves your maindisplay alone. I may actually leave this feature on, unlike with the Bolt whereI turned it off as fast as I could.&lt;/li&gt;&lt;li&gt;The map page loads as fast as any other page. On the Bolt, I would only turnthe map page on when I was riding an unfamiliar route and needed turn-by-turndirections. Every time I turned it on, though, I would forget to turn it offand I would get frustrated on my normal rides because paging through and hittingthe map page meant waiting for the device to struggle to load the map. The Edgejust shows it immediately. There&amp;rsquo;s no reason to turn the page off on thiscomputer.&lt;/li&gt;&lt;li&gt;The damn thing did what it is supposed to do for the whole ride from start tofinish. It connected all of my sensors quickly at the start, tracked velocity,and other metrics, correctly throughout the ride, and did not randomly decide topause.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The parts I&amp;rsquo;m less thrilled with:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The solar charging. Honestly, it&amp;rsquo;s a gimmick and not worth it. You &lt;em&gt;might&lt;/em&gt;get a few more minutes of charge out of it if you are someone that forgets tocharge their devices regularly. I always charge my devices on Friday, so I don&amp;rsquo;treally need the solar charging feature. Over my 40 mile ride, on the SilverComet which has a lot of shade, I got a little over a minute of extra charge.It also stops charging from the Sun if the device is too hot. So, it&amp;rsquo;s not likeyou can just leave it in direct sunlight and expect to get a full charge outof it.&lt;/li&gt;&lt;li&gt;The display. It&amp;rsquo;s way too susceptible to glare, particularly in brokensunlight. The text is large and easy to read otherwise, but it&amp;rsquo;s much, &lt;em&gt;much&lt;/em&gt;,easier to glance down and actually read the screen of the Bolt (aside from thesmall text).&lt;/li&gt;&lt;li&gt;The touch screen. I like it a lot better than I thought I would, but it&amp;rsquo;sstill a touch screen on a device that gets sweat on it. It does surprisinglywell in the rain, &lt;a href=&#34;https://www.youtube.com/watch?v=U1UQPQ8AQqk&#34;&gt;https://www.youtube.com/watch?v=U1UQPQ8AQqk&lt;/a&gt;, but I had towipe sweat off it during my ride and it resulted in the pulldown screen showingup.&lt;/li&gt;&lt;li&gt;The start/pause is not as clear as with the Bolt. It&amp;rsquo;s just a thing that willtake getting used to, but I do like it better on the Bolt.&lt;/li&gt;&lt;li&gt;Configuration. There are a lot of features on this computer. The result isa confusing mess of menus to get lost in. Both on the device and in the phoneapp.&lt;/li&gt;&lt;li&gt;It feels way more likely to suffer damage from an accidental drop than theBolt. The Bolt is quite rugged. I do not get the same impression with the Edge.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The gallery below shows the primary screen I used while riding, and the postride summary screens.&lt;/p&gt;      &lt;div class=&#34;image-gallery&#34;&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;edge/IMG_3374.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/edge/IMG_3374_hu20c0e7e67ee1690ed6534b4bf5a18900_1036871_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;edge/IMG_3375.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/edge/IMG_3375_huffeb95fbf79910c405b5f0d415f08f9d_3082075_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;edge/IMG_3376.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/edge/IMG_3376_huffeb95fbf79910c405b5f0d415f08f9d_3381425_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;edge/IMG_3377.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/edge/IMG_3377_huffeb95fbf79910c405b5f0d415f08f9d_3156827_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;edge/IMG_3378.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/edge/IMG_3378_huffeb95fbf79910c405b5f0d415f08f9d_3263444_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;edge/IMG_3379.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/edge/IMG_3379_huffeb95fbf79910c405b5f0d415f08f9d_3222842_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;edge/IMG_3380.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/edge/IMG_3380_hu20c0e7e67ee1690ed6534b4bf5a18900_3184953_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;edge/IMG_3381.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/edge/IMG_3381_hu20c0e7e67ee1690ed6534b4bf5a18900_3166814_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;edge/IMG_3382.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/edge/IMG_3382_huffeb95fbf79910c405b5f0d415f08f9d_3269223_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;edge/IMG_3383.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/edge/IMG_3383_huffeb95fbf79910c405b5f0d415f08f9d_3320773_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;edge/IMG_3384.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/edge/IMG_3384_huffeb95fbf79910c405b5f0d415f08f9d_3579282_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;edge/IMG_3385.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/edge/IMG_3385_huffeb95fbf79910c405b5f0d415f08f9d_3186591_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;edge/IMG_3386.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/edge/IMG_3386_huffeb95fbf79910c405b5f0d415f08f9d_3339495_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;edge/IMG_3387.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/07/04/bolt-v2-edge-1040/edge/IMG_3387_huffeb95fbf79910c405b5f0d415f08f9d_3387831_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;      &lt;/div&gt;&lt;h2 id=&#34;summary&#34;&gt;  Summary  &lt;a href=&#34;#summary&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;In short: as a long time Wahoo Bolt user, I am quite happy with the Garmin Edgeas a replacement. It&amp;rsquo;s a much more robust computer, in size, feature set, andoperation. Even for a basic user like myself, it does everything one would wantit to do. But I do not recommend wasting money on the Solar version; get thestandard version.&lt;/p&gt;</description>
     </item>
   
     <item>
       <title>Chain Waxing</title>
       <link>https://jrfom.com/posts/2022/05/08/chain-waxing/</link>
       <pubDate>Sun, 08 May 2022 17:00:00 -0400</pubDate>
       
       <guid>https://jrfom.com/posts/2022/05/08/chain-waxing/</guid>
       <description>&lt;p&gt;When I started my cycling hobby in 2014 I started out with a &lt;a href=&#34;https://web.archive.org/web/20201112034340/https://archive.trekbikes.com/us/en/2014/Trek/7_2_fx&#34;&gt;Trek FX7.2&lt;/a&gt;, as seen in Figure 1. I put roughly 2,500 miles on that bike,and I think the most maintenance I ever did to the chain was to wipe it with acloth before putting more &lt;a href=&#34;https://web.archive.org/web/20220422180818/https://www.triflowlubricants.com/product/tri-flow-superior-lubricant-drip-bottle/&#34;&gt;lubricant&lt;/a&gt; on. When I upgraded to my&lt;a href=&#34;https://web.archive.org/web/20210511174403/https://archive.trekbikes.com/us/en/2017/Trek/crossrip_3&#34;&gt;Crossrip 3&lt;/a&gt; in 2018, Figure 2, I started doing better. I put almost9,000 miles on that bike and I routinely ran the chain through a handheldcleaner device, dried it, and then re-applied fresh lubricant. Shortly aftergetting my latest bike, my &lt;a href=&#34;https://web.archive.org/web/20211019231849/https://www.trekbikes.com/us/en_US/bikes/road-bikes/performance-road-bikes/%C3%A9monda/%C3%A9monda-slr/%C3%A9monda-slr-7/p/32565/&#34;&gt;2021 Émonda SLR 7&lt;/a&gt;, I learned about waxingbike chains and decided to give it a try since my chain was so new.&lt;/p&gt;                &lt;style&gt;      .image-gallery {        display: grid;        grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));        gap: 0.5em;      }    &lt;/style&gt;    &lt;div class=&#34;image-gallery&#34;&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;01-trek-fx-72.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/05/08/chain-waxing/01-trek-fx-72_hud7966da0d79f7440513a55a4ca8b65d4_2327345_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;02-trek-crossrip-3.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/05/08/chain-waxing/02-trek-crossrip-3_hu1fc674dfce8e730ba4113eaa84ae6c6d_2754730_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;03-trek-emonda.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/05/08/chain-waxing/03-trek-emonda_hu31303ff7205e519cb3dfa025a0e2a3b4_3614705_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;      &lt;/div&gt;&lt;h2 id=&#34;materials&#34;&gt;  Materials  &lt;a href=&#34;#materials&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Whereas the upfront materials for maintaining a chain with web lubricant isprimarily the lubricant itself, a cleaning device, and some degreaser, thebill of materials to get started with chain waxing is a bit lengthier:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&#34;https://silca.cc/collections/chain-lube-wax/products/secret-chain-wax-blend&#34;&gt;Silca Hot Melt Wax&lt;/a&gt;: the primary wax to be used on the chain.&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://silca.cc/collections/chain-lube-wax/products/silca-super-secret-chain-lube&#34;&gt;Silca Chain Coating&lt;/a&gt;: drip wax to be used between full waxes.&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://www.amazon.com/dp/B09GJKRTS2&#34;&gt;degreaser&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://www.amazon.com/dp/B07XSD6F1Z&#34;&gt;denatured alcohol&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://www.amazon.com/dp/B09QZYLKH2&#34;&gt;lidded jars&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://www.amazon.com/dp/B00D9NW32I&#34;&gt;chain link pliers&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://www.amazon.com/dp/B09Q3C4LBR&#34;&gt;chain hook&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://www.amazon.com/dp/B07SSWF7JY&#34;&gt;chain links&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;strike&gt;&lt;a href=&#34;https://www.amazon.com/dp/B06Y1YD5W7&#34;&gt;InstantPot&lt;/a&gt;: to melt the wax with.&lt;/strike&gt;&lt;/li&gt;&lt;li&gt;&lt;strike&gt;&lt;a href=&#34;https://www.amazon.com/dp/B072K19MQV&#34;&gt;extra cooking pot&lt;/a&gt;: for the wax.&lt;/strike&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://www.amazon.com/dp/B09X1WFR7Z&#34;&gt;wax warmer&lt;/a&gt;: to melt the wax with (see &lt;a href=&#34;#update-2023-06-15&#34;&gt;Update 2023-06-15&lt;/a&gt; below)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;It&amp;rsquo;s a lot of stuff with a rather hefty upfront cost. But, as you can learnbelow, I think it was worth it.&lt;/p&gt;&lt;h2 id=&#34;preparing-the-chain&#34;&gt;  Preparing The Chain  &lt;a href=&#34;#preparing-the-chain&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Before the chain can be waxed it needs to be completely free of any currentlubricant and debris. This is best done with a completely new, unused chain,but can be done with a relatively fresh chain. When I started this experimentI had about 200 miles on my chain. The further the chain has been ridden, theless &amp;ldquo;worth it&amp;rdquo; it will be to clean it and wax it. I wish I had started witha new chain, but I think up to about 300 miles on the chain will be okay.&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://zerofrictioncycling.com.au&#34;&gt;Zero Friction Cycling&lt;/a&gt; (ZFC) has a chain prep guide that coverseverything, but the short of it is:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Soak the chain in degreaser, occasionally shaking the jar to agitate it, fora couple minutes.&lt;/li&gt;&lt;li&gt;Take the chain from the degreaser, wipe off with a towel (blue paper towelsare fine).&lt;/li&gt;&lt;li&gt;Repeat step 1 &amp;amp; 2 with another jar of fresh degreaser until the degreaserdoes not become cloudy.&lt;/li&gt;&lt;li&gt;Rinse the chain with a jar of denatured alcohol until the alcohol does notshow any particulates.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;As the ZFC guide indicates, steps 1 and 2 can be a long process. I used threejars for the degreaser and it took a full 10 rounds of degreasing before Iwas convinced the chain was clean. The short of it is that I used the &lt;em&gt;full&lt;/em&gt;1 gallon bottle of degreaser to clean the chain. And still it took two alcoholbaths to finish flushing the chain of dirt.&lt;/p&gt;&lt;h2 id=&#34;waxing-the-chain&#34;&gt;  Waxing The Chain  &lt;a href=&#34;#waxing-the-chain&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The howto that &lt;a href=&#34;https://web.archive.org/web/20220210040549/https://silca.cc/pages/how-to-apply-chain-lube&#34;&gt;Slica provides&lt;/a&gt; is fairly comprehensive and easyto follow. In short:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Put the wax into the InstantPot and set the cooker to slow cook on high. It&amp;rsquo;seasiest to put the chain on top of the wax so that it heats along with thewax.&lt;/li&gt;&lt;li&gt;Let the wax heat to about 70ºC.&lt;/li&gt;&lt;li&gt;Take the pot out of the cooker.&lt;/li&gt;&lt;li&gt;Use a device (e.g. bent wire/coat hanger) to agitate the chain in order towork the wax and additive into the chain rollers.&lt;/li&gt;&lt;li&gt;Let the wax cool until a &amp;ldquo;film&amp;rdquo; starts to develop on the surface.&lt;/li&gt;&lt;li&gt;Pull the chain from the wax and let it drip back into the pot.&lt;/li&gt;&lt;li&gt;Let the chain cool to ambient temperature.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;At this point the chain can be loosened by pulling it back and forth overa pipe. Once the links are loosened, the chain can be reinstalled on the bike.&lt;/p&gt;&lt;p&gt;Rewaxing the chain is as simple as removing it from the bike, wiping it down,and repeating the above steps.&lt;/p&gt;&lt;h2 id=&#34;ongoing-maintenance&#34;&gt;  Ongoing Maintenance  &lt;a href=&#34;#ongoing-maintenance&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;All of the information I have read on ZFC and Silca&amp;rsquo;s site/videos indicatesthat a chain should get about 300km/186mi before needing to be waxed again.I typically ride around 100mi per week. My first wax was around mid-March.It seems to me that I can get away with waxing at the start of every month bytaking advantage of the drip wax. So, thus far I have waxed my chain twice:once in mid-March and once on May 1. Between those waxes I applied the dripwax twice. The below image gallery shows all of the steps in the rewaxingprocess from that May 1, 2022 waxing session.&lt;/p&gt;      &lt;div class=&#34;image-gallery&#34;&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;rewax/01.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/05/08/chain-waxing/rewax/01_hu17f6fc57800805231f8a83dfe8120a73_3876017_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;rewax/02.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/05/08/chain-waxing/rewax/02_hue07fd3d22e7f62ee7ed382fc71991253_2677967_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;rewax/03.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/05/08/chain-waxing/rewax/03_hu41b5eccdc1f7ec0a9ef93a4e0ef1c390_1948708_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;rewax/04.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/05/08/chain-waxing/rewax/04_hu1f9ca2e70afba8533dbb28178fcf841d_2964483_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;rewax/05.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/05/08/chain-waxing/rewax/05_hu158d6bd7d0b939d901ca63bad758fa78_2538057_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;rewax/06.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/05/08/chain-waxing/rewax/06_hufdce30fe4119cbf6933fc81c73df9714_2479112_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;rewax/07.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/05/08/chain-waxing/rewax/07_hucb6afac2ba4a60af10b5924f1d67b36f_6205172_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;rewax/08.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/05/08/chain-waxing/rewax/08_hubba4db682da68ffce2dbf24e052696d4_2276725_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;rewax/09.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/05/08/chain-waxing/rewax/09_hub13e58c00c48dcc430926b678b823f3f_2866717_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;rewax/10.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/05/08/chain-waxing/rewax/10_hu08c4110402e76e58bd4d39f7669ad29a_2219870_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;      &lt;/div&gt;&lt;p&gt;The first image shows how much dirt I removed from the chain prior to puttingit in the pot for waxing. It&amp;rsquo;s one paper towel that was used to remove dirtfrom about a month and a half of riding. The towel is unbelievably clean;especially compared to the amount of black grease that would come from anequally ridden chain using regular wet lubricant.&lt;/p&gt;&lt;p&gt;Two of the images show me measuring the temperature: first of the wax as it isbeing heated and the second of the chain to show it has reached ambienttemperature. I &lt;em&gt;highly&lt;/em&gt; recommend getting a laser thermometer to help with thisprocess. Guessing that things have reached temperature is not easy.&lt;/p&gt;&lt;p&gt;One of the images shows the tool I built for loosening the chain. It&amp;rsquo;s asmall 1 square foot sheet of plywood with an iron pipe screwed into an ironfloor flange attached to the plywood. I would have used PVC pipe, but I couldnot find a floor flange in PVC.&lt;/p&gt;&lt;p&gt;Finally, two of the images show the links where the quick link will be added.In the images I am showing that I &lt;em&gt;remove&lt;/em&gt; the wax from the surface of thoselinks. I do this because the quick link tolerance is so tight that it isbasically impossible to install if the wax is present on those surfaces.Removing this was is okay because the point is for the wax to be inside therollers, where the primary friction happens.&lt;/p&gt;&lt;p&gt;After putting the chain back on the bike it is a good idea to run the chainaround the drivetrain for a couple minutes. This allows most of the wax that isgoing to flake off to go ahead and flake off so that you can wipe it off theframe.&lt;/p&gt;&lt;p&gt;From here, apply drip wax about every 100 miles or every two weeks, dependingon riding time. Applying the drip wax is very similar to applying wet lubricant.Wipe the chain with a rag and then drip one or two drips of wax on each roller.Work each drop of wax into the roller by rolling the roller with your fingers.&lt;/p&gt;&lt;h2 id=&#34;chain-noise&#34;&gt;  Chain Noise  &lt;a href=&#34;#chain-noise&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The Shimano chains are extremely quiet when properly lubricated. One fear I hadgoing in to this experiment was if the chain would remain quiet. There are manyarticles and videos on the web detailing everything I have already detailed inthis post, but they stop short of demonstrating what the chain &lt;em&gt;actually&lt;/em&gt; soundslike. They always state &amp;ldquo;the chain is whisper quiet&amp;rdquo; or something similar. Thatstatement is mostly true. The following video shows the amount of noise thechain makes with about 100mi on the chain &lt;em&gt;subsequent&lt;/em&gt; to a drip waxmaintenence:&lt;/p&gt;&lt;video controls autoplay=&#34;false&#34; style=&#34;width: 100%&#34;&gt;  &lt;source src=&#34;chain-noise-with-worn-wax.mov&#34; type=&#34;video/quicktime&#34; /&gt;&lt;/video&gt;&lt;p&gt;Notice that it isn&amp;rsquo;t annoyingly noisy, but there is definitely a noticeableclicking. A freshly hot waxed chain is shown in this video:&lt;/p&gt;&lt;video controls autoplay=&#34;false&#34; style=&#34;width: 100%&#34;&gt;  &lt;source src=&#34;chain-noise-fresh-wax.mov&#34; type=&#34;video/quicktime&#34; /&gt;&lt;/video&gt;&lt;h2 id=&#34;summary&#34;&gt;  Summary  &lt;a href=&#34;#summary&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I went into this experiment not knowing what to expect. My goal was to see ifI could get a chain that would be easier to keep clean and maintained with lesseffort. After two waxings, my conclusion is: yes, this is going to work. The wayI was cleaning my chain prior to re-lubricating it was very inefficient. I feltlike it needed to be cleaned &lt;em&gt;every week&lt;/em&gt;; if not even more often. And I wasgetting frustrated enough with the chain on method that was I was likely tomove up to a chain off once per month method anyway.&lt;/p&gt;&lt;p&gt;The waxing method I described above is about an hour of maintenance from startto finish. While the chain and wax are heating up I can thoroughly wash my bike.And believe me, the &lt;a href=&#34;https://en.wikipedia.org/wiki/Silver_Comet_Trail&#34;&gt;SilverComet&lt;/a&gt; trail that I ride alomstevery Saturday, puts &lt;em&gt;plenty&lt;/em&gt; of dirt on my bike (&lt;em&gt;and&lt;/em&gt; me) after just one rideto justify a good washing (I really don&amp;rsquo;t understand how that trail imparts moredirt than any public road I ride).&lt;/p&gt;&lt;p&gt;Given the longevity of a pot of wax (Silca claims somewhere around 30 waxes?),the lack of grease picking up dirt, the lack of random chainring tattoos, andthe minimal impact to maintenance time, I forsee myself sticking with waxing.&lt;/p&gt;&lt;h2 id=&#34;update-2023-04-13&#34;&gt;  Update 2023-04-13  &lt;a href=&#34;#update-2023-04-13&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Since writing this article I have devised a couple of tips that make maintenance easier:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Applying the drip wax between hot waxings can be done without much effort. It is plenty effective to apply a drop along the top of each roller between the chainring and the pulley wheel, massaging the wax into the rollers, and advancing the chain for the next set of links. This process is far quicker than individually massaging each roller, and works just as well.&lt;/li&gt;&lt;li&gt;There is no need to hot wax the quick link. It is sufficient to hot wax the full chain, put it back on the bike and link it together with the quick link, and then apply some drip wax to the pins of the quick link.&lt;/li&gt;&lt;li&gt;It&amp;rsquo;s a good idea to perform a quick degreaser and denatured alcohol rinse of the chain every few months to remove internal dirt. One round of each cleaner should be enough. Let the chain fully dry afterward, and then proceed with a standard hot wax.&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=&#34;update-2023-06-15&#34;&gt;  Update 2023-06-15  &lt;a href=&#34;#update-2023-06-15&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I have switched to using a dedicated &lt;a href=&#34;https://www.amazon.com/dp/B09X1WFR7Z&#34;&gt;wax warmer&lt;/a&gt; instead of using an InstantPot for melting the wax. The InstantPot heats the wax fairly quickly, but it doesn&amp;rsquo;t &lt;em&gt;stop&lt;/em&gt; heating the wax. This means the temperature has to be regularly monitored in order to remove the pot from the heat before the wax reaches its combustion point. With the wax warmer, it&amp;rsquo;s very easy to set a desired temperature and the warmer will maintain it.&lt;/p&gt;&lt;p&gt;As can be seen in the images below, I have my warmer set to roughly 80ºC. It takes about an &lt;em&gt;hour&lt;/em&gt; for the warmer to melt the wax (far slower than the InstantPot), and it isn&amp;rsquo;t completely accurate to the set temperature. My warmer seems to be around 2 to 3 degrees off on the dial. So my 80ºC setting ends up with the wax maintaining temperature at around 83ºC.&lt;/p&gt;&lt;p&gt;This is fine, though. I can set the warmer in action about an hour before I plan to perform the maintenance on my bicycle, and it&amp;rsquo;ll be ready when I am. I also no longer need to put the chain in the pot prior to turning the heat on in order to get the chain hot at the same time as the wax. Since the warmer is going to maintain a non-combustible temperature, I can put the chain in the wax after it has melted, deal with other bike maintenance (e.g. washing it) while the chain cooks, and then pull it when I feel it has simmered long enough.&lt;/p&gt;&lt;p&gt;I highly recommend going the dedicated wax warmer route. I opted for a cheap one, but if you have the cash, you can probably find one with a digital temperature control. But a cheap one where you have determined the dial and actual temperature variance is plenty sufficient for the task.&lt;/p&gt;      &lt;div class=&#34;image-gallery&#34;&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;wax-warmer/IMG_3843.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/05/08/chain-waxing/wax-warmer/IMG_3843_hu7f4735c9f1535e0fe9395518698bfad1_8446400_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;wax-warmer/IMG_3844.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/05/08/chain-waxing/wax-warmer/IMG_3844_hub9d8017537b333c887216ec16120d754_7303293_480x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;      &lt;/div&gt;</description>
     </item>
   
     <item>
       <title>A Shitty Day</title>
       <link>https://jrfom.com/posts/2022/03/14/a-shitty-day/</link>
       <pubDate>Tue, 15 Mar 2022 19:20:00 -0400</pubDate>
       
       <guid>https://jrfom.com/posts/2022/03/14/a-shitty-day/</guid>
       <description>&lt;p&gt;It&amp;rsquo;s difficult to write this, but I feel like I need to write it down, howeverrandom and sloppily it turns out:&lt;/p&gt;&lt;p&gt;I got laid off today.&lt;/p&gt;&lt;p&gt;I can&amp;rsquo;t say the layoffs were a surprise. Internal events were telegraphing thatit was likely to happen. I was just crossing my fingers that I wouldn&amp;rsquo;t beincluded. I spent the past four years putting everything I could into makingKnock a success. I feel like I showed how capable Iam, and that I did tremendous work. But the company is not doingwellat all:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;The company on Tuesday announced a private fundraising round including $70million in equity and $150 million in new debt&amp;hellip;&lt;/p&gt;&lt;p&gt;The forecast pales in comparison to the $400 million to $500 million Knockhoped in March 2021 to raise in an IPO. At the time, Knock was aiming for avaluation of $2 billion; Black hasn’t disclosed the company’s valuation afterthe latest fundraising round, but cited money as a reason for the layoffs.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;It also pales in comparison to the &lt;a href=&#34;https://www.crunchbase.com/organization/knockaway/company_financials&#34;&gt;$400m SeriesB&lt;/a&gt; round.&lt;/p&gt;&lt;p&gt;It really hurts to see my face right in the middle of the company picture in&lt;a href=&#34;https://web.archive.org/web/20220315222933/https://www.seanblack.com/blog/wild-ride-from-2b-to-220m&#34;&gt;Sean&amp;rsquo;s blogpost&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The absence of the people that were let go will have a major impact. People witha lot of knowledge around the building blocks of the whole platform were laidoff. The people remaining are really smart and will figure things out, but I donot envy the road ahead of them.&lt;/p&gt;&lt;p&gt;I am trying to accept this whole thing and move forward. I have to keepreminding myself that, regardless of what is written in the links above, themarket today is a strong one for people with my skills. I have to keep remindingmyself that I have a proven body of public work. And I have to keep remindingmyself that my time with Knock was an invaluable learning experience where Igrew significantly in many ways.&lt;/p&gt;&lt;p&gt;But for today, it&amp;rsquo;s really, really, hard to let all of that sink in.&lt;/p&gt;&lt;p&gt;To close out, I&amp;rsquo;m leaving a few of the kind words my colleagues said about meduring my tenure there. The names are redacted as I don&amp;rsquo;t have their permission,but I doubt they will mind me sharing some amount of positivity on thisterrible day.&lt;/p&gt;                &lt;style&gt;      .image-gallery {        display: grid;        grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));        gap: 0.5em;      }    &lt;/style&gt;    &lt;div class=&#34;image-gallery&#34;&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;2019-11-07_-_Knockstar_Awards_Nominations.png&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/03/14/a-shitty-day/2019-11-07_-_Knockstar_Awards_Nominations_hucf2f96e764a0ab23c6cd4d3b4205ca42_167391_480x0_resize_q80_box_3.png&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;2020-03-12_-_High_Five.png&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/03/14/a-shitty-day/2020-03-12_-_High_Five_hu328cbc20cb2b493c5634b742ff8b0d52_70776_480x0_resize_q80_box_3.png&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;2020-05-20_-_High_Five.png&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/03/14/a-shitty-day/2020-05-20_-_High_Five_hu7d52c3406e9027a1784a3cfcb00d90b3_79364_480x0_resize_q80_box_3.png&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;2021-11-02_All_Hands_commendations.png&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/03/14/a-shitty-day/2021-11-02_All_Hands_commendations_hu687ad880e5c5a8594f5406118b00e480_123462_480x0_resize_q80_box_3.png&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;2021-11-17.png&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2022/03/14/a-shitty-day/2021-11-17_hu7782d142e140ef5f61da255f1d08693b_203125_480x0_resize_q80_box_3.png&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;      &lt;/div&gt;</description>
     </item>
   
     <item>
       <title>My Career Path To Date</title>
       <link>https://jrfom.com/posts/2021/11/17/career-path/</link>
       <pubDate>Wed, 17 Nov 2021 20:45:00 -0500</pubDate>
       
       <guid>https://jrfom.com/posts/2021/11/17/career-path/</guid>
       <description>&lt;p&gt;Today, I received a private message on Twitter:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&amp;lsquo;A software engineer with a background in Linux server administration&amp;rsquo; - Thisis music to my ears because I am trying to forge a similar path. Let me knowif you have any tips.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;It was in reference to the current tagline I have on my resume site,&lt;a href=&#34;https://james.sumners.info/&#34;&gt;james.sumners.info&lt;/a&gt;. I responded with a very shortsummary, but I realized that I haven&amp;rsquo;t written about it here. I thought I had in&lt;a href=&#34;https://jrfom.com/posts/2018/04/30/a-new-career/&#34;&gt;A New Carerer&lt;/a&gt; or even &lt;a href=&#34;https://jrfom.com/posts/2020/05/19/new-title-who-dis/&#34;&gt;A Rumination On APromotion&lt;/a&gt; (I touched on it, but only from theperspective of how trepidatious it can be), but I clearly had not. This topicsurfaces rather regularly in the Twitter circles I pay attention to. Given thatmy path has been anything but ideal, or ordinary, I think it is worth relatinghere.&lt;/p&gt;&lt;h2 id=&#34;the-beginning&#34;&gt;  The Beginning  &lt;a href=&#34;#the-beginning&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;In my view, my career started with my position as a technical support consultantat &lt;a href=&#34;https://clayton.edu&#34;&gt;Clayton State University&lt;/a&gt;. That&amp;rsquo;s because I was doingtech support there for &lt;em&gt;many&lt;/em&gt; years. I started in 1999, and left the position in2008 when I graduated.&lt;/p&gt;&lt;p&gt;That&amp;rsquo;s right, I was in university all that time as a student; indeed, I starteduniversity in the autumn of 1998. I was not ready for university when I started,and had to scale way back in order to focus on the core curriculum and succeed.After one semester, my GPA was 2.0; by graduation, it was 2.92. I &lt;em&gt;almost&lt;/em&gt; gotit back above 3.0 with many consecutive ≥3.0 semesters. I relate the story of myacademic struggle/perseverance as proof that my path has not been ideal. Also,to show that even such an abysmal start can be overcome with hard work.&lt;/p&gt;&lt;p&gt;Throughout the whole time I was pushing through university, I was eitherfrontline technical support or a &amp;ldquo;student assistant&amp;rdquo; in the networkingdepartment (&amp;ldquo;backend&amp;rdquo; technical support). Being at a small &amp;ldquo;community&amp;rdquo;university meant that people who showed initative to solve problems were allowedto do so. While in the frontline position I wrote webapps to things likescheduling support appointments and tracking who used what tools and how oftenthose tools were used (by writing a site that required authorization and trackeddownloads). I also experimented with various Linux distributions, ultimatelyrunning Linux as my fulltime desktop operating system. Which is what led to thenext step in my career.&lt;/p&gt;&lt;h2 id=&#34;going-full-time&#34;&gt;  Going Full Time  &lt;a href=&#34;#going-full-time&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;As I mentioned, I graduated in 2008. This meant two things: first, I could nolonger be employed as a student worker; and second, there were no jobs to be hadin the &lt;a href=&#34;https://en.wikipedia.org/wiki/Great_Recession&#34;&gt;Great Recession&lt;/a&gt;. But Ihad developed a reputation in the Office of Information and Technology Services(OITS), the department I worked in as a student work, as fairly decentdeveloper. Thus, when the director of the student information servicessubdepartment opened a role for a .Net developer, he called me, interviewed me,and ultimately hired me.&lt;/p&gt;&lt;p&gt;I failed pretty hard in the .Net role. It was an unfamiliar framework for me,and to this day I maintain that it was never designed to be a web applicationframework (the request model is just &lt;em&gt;wrong&lt;/em&gt;). But one of my coworkers, who wasadministering the campus&amp;rsquo;s student web portal, &lt;a href=&#34;https://web.archive.org/web/20210128154051/https://mrfrosti.com/2010/03/09/last-week-at-clayton-state/&#34;&gt;took a new position&lt;/a&gt;,leaving a different role open that I was able to fill. This role wastechinically an application administrator role for a proprietary web portalproduct, but it grew into a niche Linux administrator role. Originally theproduct was only certified on Solaris, but the next release, that we had toupgrade to right as I transitioned into the role, required Red Hat EnterpriseLinux (RHEL).&lt;/p&gt;&lt;h2 id=&#34;linux-admin-web-developer-both&#34;&gt;  Linux Admin? Web Developer? Both?  &lt;a href=&#34;#linux-admin-web-developer-both&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Over time, the semi-product slash Linux admin role required more and more actualLinux administration. Specifically, other products we used from the same companyrequired RHEL. And since those products were to be administered by thesubdepartment I was in, I got to administer them from the operating system up.It went this way for a couple of years until the director who hired me left,along with the director of the &amp;ldquo;networking&amp;rdquo; department. The networking director(really, &amp;ldquo;telecom&amp;rdquo;) came to me and asked which deparment I thought &lt;em&gt;actually&lt;/em&gt;fit my role. My answer: his.&lt;/p&gt;&lt;p&gt;This is where I transitioned to a full time Linux administrator for all of theLinux based business systems operated by the university. I really shined in theLinux administrator role. By the time I left, I had all of those systemsbootstrappable from nothing to ready for the target application in a matter ofminutes through use of &lt;a href=&#34;https://ipxe.org&#34;&gt;iPXE&lt;/a&gt;, Red Hat Satellite, and&lt;a href=&#34;https://en.wikipedia.org/wiki/Ansible_(software)&#34;&gt;Ansible&lt;/a&gt;. And I had to standup a &lt;em&gt;lot&lt;/em&gt; of systems.&lt;/p&gt;&lt;p&gt;But I retained the administratorship of that student web portal. Eventually, theversion we were using was end-of-lifed and we had to come up with a solution toreplace it. The product was utter garbage, the only thing our students ever usedwithin it was single sign-on to other products, and that didn&amp;rsquo;t actually workwithout &lt;em&gt;my own code to fix it&lt;/em&gt;. So I proposed we write our own portal. Giventhat I knew all of the requirements, and implemented the only feature we used, Iwas granted permission to develop the new portal on my own. Reaally, it wasmeant to be a collaboration between me and &lt;a href=&#34;https://caseyscarborough.com&#34;&gt;anothercoworker&lt;/a&gt;, but he left right at the start of theproject. Since it ended up being just me on the project, it ended up takingabout a year to complete. I wrote a full-fledged &amp;ldquo;portal&amp;rdquo;/CMS product, alongwith an account management tool, and a &lt;a href=&#34;https://github.com/jscas&#34;&gt;CASimplementation&lt;/a&gt;. All while &lt;em&gt;primarily&lt;/em&gt; being thecampus&amp;rsquo;s Linux system administrator.&lt;/p&gt;&lt;p&gt;One of the first things I knew I would need in the web portal project would be agood logger. Prior to my collaborator leaving, we were going to write the portalin Java and Spring. This meant I would have had access to&lt;a href=&#34;http://www.slf4j.org&#34;&gt;slf4j&lt;/a&gt;. But since I was now on my own, I knew I had tochange the language and framework. Java and Spring were too heavy for one personto write something of this scope. So I decided to give Node.js another shot; Ihad used it in the 0.x days and found it too volatile for a production project,but Io.js had just merged back into Node.js as version 4.0.0, along with a brandnew long term support policy. So, I went looking for a logger. None of thepopular Node.js loggers would work because it was &lt;em&gt;obvious&lt;/em&gt; they would bebottlenecks to the application. I despaired, thinking I would have to write myown, but after digging through several pages of NPM search results, I cameacross &lt;a href=&#34;https://github.com/pinojs/pino&#34;&gt;Pino&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Pino was perfect. It did &lt;em&gt;exactly&lt;/em&gt; what I was planning to do in my own logger,except better. It got out of the way of the event loop as much as feasiblypossible, and provided the familiar Log4j interface. The work I was doing led tome contributing back to the project. This ultimately led to the story related in&lt;a href=&#34;https://jrfom.com/posts/2018/03/07/fastify-story/&#34;&gt;My Fastify Story&lt;/a&gt;; which is part of &lt;em&gt;this&lt;/em&gt; story, butI will not re-hash it here. The short of it is that it led to me becoming amaintainer of both Pino and &lt;a href=&#34;https://github.com/fastify/fastify&#34;&gt;Fastify&lt;/a&gt;.&lt;/p&gt;&lt;h2 id=&#34;moving-on-to-knockcom&#34;&gt;  Moving On To Knock.com  &lt;a href=&#34;#moving-on-to-knockcom&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;On January 4, 2015 I told a friend to come over to my house so we could worktogether to write resume sites for ourselves. He wanted to be become a full timedesigner and I wanted to become a full time software engineer. For me, thatended up being &lt;a href=&#34;https://james.sumners.info&#34;&gt;james.sumners.info&lt;/a&gt; (&lt;a href=&#34;https://github.com/jsumners/jsumners.github.io/commit/1fb6697a4d21584948293cf01620eadcb83bbbd9&#34;&gt;firstcommit&lt;/a&gt;).This decision would prove to the a pivotal decision my life: it&amp;rsquo;s the one thatled to me actually landing a software engineering role that I could excel at,and I do believe I have.&lt;/p&gt;&lt;p&gt;On January 30, 2018 I was laying on my couch watching television when I receiveda text message I&amp;rsquo;ll never forget:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Hi James, I am Karan. One of the cofounders of knock.com - loved a few of yourrepos. I hope you are seeking opportunity, if you are, would love 5 mins ofyour time.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;He had discovered my work through researching backend Node.js frameworks. Whichtranslates to:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Reviewing the Fastify and Pino projects.&lt;/li&gt;&lt;li&gt;Reviewing the major contributors and their profiles.&lt;/li&gt;&lt;li&gt;Landing on &lt;a href=&#34;https://james.sumners.info&#34;&gt;james.sumners.info&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Using the phone number on that page to send me a text.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;On May 1, 2018 I started my new career as a software engineer. Today, myposition is &amp;ldquo;senior software engineer&amp;rdquo;.&lt;/p&gt;&lt;h2 id=&#34;summary&#34;&gt;  Summary  &lt;a href=&#34;#summary&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Going back the Twitter message that spawned this lengthy post: it&amp;rsquo;s possible tostart a new career by contributing to open source projects. I have done it. Theway I see it, it requires:&lt;/p&gt;&lt;p&gt;Picking the right project, or set of projects, to contribute to. You areunlikely to succeed in this venture if you start a project of your own, or picksome obscure project only the author and &lt;em&gt;maybe&lt;/em&gt; two other people use. At thesame time, the project(s) you pick shouldn&amp;rsquo;t be so big that your contributionsget lost in the noise. You &lt;em&gt;must&lt;/em&gt; be interested in the projects, as it will showthrough in your work and your long term commitment. You could pick some bigproject like React, but you&amp;rsquo;ll have to work extra hard to gain recognition. Pinoand Fastify are still excellent candidates (as of this writing). My generalrecommendation for helping decide is to look for projects that are still rathernascent, but are being championed by well known individuals at conferences. Theyare giving talks about those projects specifically to drum up interest andacquire a contributor pool.&lt;/p&gt;&lt;p&gt;Once you decide on the project(s), start small by triaging issues. This could beasking questions of the issue reporters to get clarification and writing areproduction case, or &lt;a href=&#34;https://jrfom.com/posts/2017/03/08/a-primer-on-contributing-to-projects-with-git/&#34;&gt;submitting pull requests&lt;/a&gt; tosolve the issues. If you show respect for the project maintainers, accept theirfeedback as helpful and not a comment on your ability, and show you&amp;rsquo;re there forthe long haul, your work will be recognized.&lt;/p&gt;&lt;p&gt;All of this isn&amp;rsquo;t to say that my path is typical. It isn&amp;rsquo;t. I was &lt;em&gt;extremlylucky&lt;/em&gt; that the right person recognized my work and reached out. This is highlyunlikely to happen without your own prodding. If you&amp;rsquo;re trying to switchcareers, or even just start out a career, by contributing to open source, you&amp;rsquo;llvery likely need to start actively presenting your work to potential employers.Just know that it is a viable route that can succeed with enough effort on yourpart.&lt;/p&gt;</description>
     </item>
   
     <item>
       <title>My Opinions On Wahoo Fitness</title>
       <link>https://jrfom.com/posts/2021/10/19/wahoo-thoughts/</link>
       <pubDate>Tue, 19 Oct 2021 20:50:00 -0400</pubDate>
       
       <guid>https://jrfom.com/posts/2021/10/19/wahoo-thoughts/</guid>
       <description>&lt;p&gt;I have mixed opinions of &lt;a href=&#34;https://www.wahoofitness.com&#34;&gt;Wahoo Fitness&lt;/a&gt; products. In chronologicalorder, I have owned and extensively used:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&#34;https://web.archive.org/web/20201020125531/https://www.engadget.com/2013-08-23-wahoo-fitness-protkt-bike-mount-and-protective-case-in-one.html&#34;&gt;PROTKT Bike Mount and Case&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://web.archive.org/web/20210519184843/https://www.dcrainmaker.com/2014/01/wahoo-fitness-tickr.html&#34;&gt;2014 Tickr&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://web.archive.org/web/20210823020622/https://www.dcrainmaker.com/2017/03/wahoo-elemnt-bolt-in-depth-review.html&#34;&gt;Bolt v1&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://web.archive.org/web/20210227030922/https://www.dcrainmaker.com/2018/07/wahoo-kickr-2018-trainer-in-depth-review.html&#34;&gt;2018 Kickr&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://web.archive.org/web/20210525131328/https://www.dcrainmaker.com/2021/05/wahoo-elemnt-bolt-v2-2021-with-color-screen-maps-a-review-in-progress.html&#34;&gt;Bolt v2&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://web.archive.org/web/20210127002123/https://www.dcrainmaker.com/2020/05/wahoos-new-2020-tickr-tickr-x-in-depth-review.html&#34;&gt;2020 Tickr&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://web.archive.org/web/20210816063907/https://www.dcrainmaker.com/2019/12/wahoo-kickr-bike-in-depth-review.html&#34;&gt;Kickr Bike v1&lt;/a&gt; (excluded from &amp;ldquo;extensive&amp;rdquo; as I just acquired this)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I&amp;rsquo;m not going to go into a review of all of those products here, there&amp;rsquo;s plentyof those out there for all of them, but I want to cover some highlights from myperspective.&lt;/p&gt;&lt;p&gt;Up front, though, let me say that I prefer Wahoo products over any others.In terms of connected sports accessories, I think they do the right thing bystarting with management via a smart phone. That being said, let&amp;rsquo;s get intoa bit of history and then into the details.&lt;/p&gt;&lt;h2 id=&#34;getting-started&#34;&gt;  Getting Started  &lt;a href=&#34;#getting-started&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I got started with cycling as a hobby in 2014. Being the tech geek that I am, Iof course wanted to keep track of my rides with my phone. The PROTKT fit thebill perfectly. I didn&amp;rsquo;t have to keep a case on my phone when I wasn&amp;rsquo;t riding,it was easy to put my phone in the case for riding, was water resistant andworked great. It set the bar pretty high for me, and I was disappointed whenthey didn&amp;rsquo;t continue the line with the next iPhone revision.&lt;/p&gt;&lt;h2 id=&#34;tick-tock&#34;&gt;  Tick Tock  &lt;a href=&#34;#tick-tock&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;As I progressed in my hobby, I added the Tickr heart monitor to my kit. Itworked fantastically until the summer of 2020. At this point, it started to notconnect consistently to my bike computer. I&amp;rsquo;d start a ride and it wouldn&amp;rsquo;t startreporting any data until a few miles into the ride. Replacing the battery didnot help. So I decided I had simply used it up and bought the latest iteration:the &lt;a href=&#34;https://web.archive.org/web/20210127002123/https://www.dcrainmaker.com/2020/05/wahoos-new-2020-tickr-tickr-x-in-depth-review.html&#34;&gt;2020 Tickr&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Not only was I having the exact same problem with the brand new version, butwhen I did get it to connect it would start off with wildly varying heart rates.It&amp;rsquo;d go from 70bpm to 120bpm and back &lt;em&gt;as I was standing still preparing tomount my bike&lt;/em&gt;. Not only is my resting heart rate between 50 and 60 beats perminute, it certainly doesn&amp;rsquo;t jump around by almost 2x the baseline. So I boughta &lt;a href=&#34;https://www.amazon.com/dp/B08411DQ96/&#34;&gt;Polar H9&lt;/a&gt; as a replacement.&lt;/p&gt;&lt;p&gt;I wish I could keep using the 2020 Tickr. The strap is better. It&amp;rsquo;s easier toclasp, easier to tell when it is powered on, and is generally more comfortable.But the Polar works and, so far, hasn&amp;rsquo;t up and decided to stop working for nodiscernible reason.&lt;/p&gt;&lt;h2 id=&#34;graduating-to-a-bike-computer&#34;&gt;  Graduating To A Bike Computer  &lt;a href=&#34;#graduating-to-a-bike-computer&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;In 2018 I bought a new bike. I upgraded from the &lt;a href=&#34;https://web.archive.org/web/20210813221405/https://en.wikipedia.org/wiki/Hybrid_bicycle&#34;&gt;hybrid bike&lt;/a&gt; Istarted out with (a &lt;a href=&#34;https://web.archive.org/web/20201112034340/https://archive.trekbikes.com/us/en/2014/Trek/7_2_fx#/us/en/2014/Trek/7_2_fx/details&#34;&gt;2014 Trek FX 7.2&lt;/a&gt;) to what I consider a &lt;a href=&#34;https://web.archive.org/web/20211008045612/https://www.bikeradar.com/advice/buyers-guides/what-is-a-touring-bike/&#34;&gt;touringbike&lt;/a&gt;: the &lt;a href=&#34;https://web.archive.org/web/20211019231425/https://www.trekbikes.com/us/en_US/bikes/hybrid-bikes/urban-commuter-bikes/crossrip/crossrip-3/p/17029/&#34;&gt;2018 Crossrip 3&lt;/a&gt; (looking forward to my&lt;a href=&#34;http://web.archive.org/web/20210825152629/https://cyclingtips.com/2020/06/2021-trek-emonda-review/&#34;&gt;2021 Émonda SLR 7&lt;/a&gt;!). When I bought my new bike, the cheap phonemount I had snapped off and dropped my phone onto the road. So I gave in got abike computer: the &lt;a href=&#34;https://web.archive.org/web/20210823020622/https://www.dcrainmaker.com/2017/03/wahoo-elemnt-bolt-in-depth-review.html&#34;&gt;Bolt v1&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I thought a bike computer was silly when I already had a phone that could doeverything and more. I was very wrong. The Bolt v1 was another big leap in myhobby. It kept much more accurate data, including temperature and elevation thatwasn&amp;rsquo;t estimated, was much easier to work with while riding, and had far betterbattery life.&lt;/p&gt;&lt;p&gt;When the Bolt v2 came out, I decided to upgrade; primarily for the color screen.I don&amp;rsquo;t quite regret it, but I&amp;rsquo;m not completely happy with it. I despise the newconvex buttons. The original concave buttons were far easier to use. The v2 isalso supposed to have a faster CPU, but it is noticeably slower to change pages(i.e. is far less responsive). But I love the color coded metrics like differentcolors for heart rate zones. It&amp;rsquo;s kind of a wash overall.&lt;/p&gt;&lt;p&gt;What really upset me about the v1 to v2 upgrade, though, is the software. Wahoodoes not provide a means to migrate all applicable settings from the v1 to thev2. Nor do they provide a way to migrate your ride history. This is despite thefact that they both use &lt;em&gt;the same&lt;/em&gt; management software. Doing a little research,I am quite confident both of these things are achievable and I could do thesecond one myself, but I don&amp;rsquo;t have time to write that one off software. Wahooshould be doing that. It&amp;rsquo;s why we pay them for their device ecosystem.&lt;/p&gt;&lt;p&gt;Further, and this is a statement about the Bolt computers in general, gettingroutes to it from &lt;a href=&#34;https://www.strava.com&#34;&gt;Strava&lt;/a&gt; is too complicated. The primary problem iswith the way Strava makes it difficult to get routes out of the app andavailable to other things. But the Bolt computer and Strava are supposed to beintegrated. On the Bolt side, the Bolt must be connected to Wi-Fi in order todownload new routes from Strava. So if you are at a remote, unfamiliar location,and want a local route you&amp;rsquo;re out-of-luck. The Bolt will not use the phone asa local &amp;ldquo;hot spot&amp;rdquo; to connect to Strava and download new routes. The computermust be directly connected to an &lt;em&gt;open&lt;/em&gt; Wi-Fi connection (i.e. one not lockedbehind a captive portal) in order to download new routes. This part is a failingof the Wahoo software.&lt;/p&gt;&lt;p&gt;As an aside, don&amp;rsquo;t expect to rely on Strava in this situation. It is uselessfor live routing. It does not announce upcoming turns.&lt;/p&gt;&lt;h2 id=&#34;kickin-it&#34;&gt;  Kickin&amp;rsquo; It  &lt;a href=&#34;#kickin-it&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;For the 2019/2020 cold season I bought the &lt;a href=&#34;https://web.archive.org/web/20210227030922/https://www.dcrainmaker.com/2018/07/wahoo-kickr-2018-trainer-in-depth-review.html&#34;&gt;Kickr&lt;/a&gt; to use to keep myconditioning up. It worked beautifully. I was able to get back outside in lateMarch and start riding like I never stopped riding outside. Same for the nextseason. My only gripes with the trainer were that my rear axle clamp kept comingloose; the cogs didn&amp;rsquo;t match the wear on my chain (or alignment of my shifter?),which resulted in grinding gears and clunky shifting; and all of the damage thesweat pouring into my stem caused. All of this is avoidable/manageable withproper setup and prevention. I&amp;rsquo;d definitely recommend the trainer if you&amp;rsquo;relooking for one.&lt;/p&gt;&lt;h2 id=&#34;stepping-up-my-indoor-game&#34;&gt;  Stepping Up My Indoor Game  &lt;a href=&#34;#stepping-up-my-indoor-game&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;For the 2021/2022 cold season I decided to upgrade to the &lt;a href=&#34;https://web.archive.org/web/20210816063907/https://www.dcrainmaker.com/2019/12/wahoo-kickr-bike-in-depth-review.html&#34;&gt;Kickr Bike&lt;/a&gt;.I was torn between this bike and the &lt;a href=&#34;https://web.archive.org/web/20210125011651/https://stagescycling.com/us/stagesbike/&#34;&gt;Stages bike&lt;/a&gt;. Ultimately, Iopted for the Kickr due to the more road bike-like configuration and shifting. Ihave ridden it eight times. I can already tell that I am happy with thepurchase, but there are a few items that bother me:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The Stages bike is cheaper, clearly more sturdy, and ships with &amp;ldquo;free&amp;rdquo;shipping. The Kickr, shipped direct from Wahoo (who&amp;rsquo;s headquarters is ~40miles from my house), was an extra $150 for me to get shipped.&lt;/li&gt;&lt;li&gt;The Kickr ships with cheap parts they seemingly know you&amp;rsquo;ll replace: pedals,handlebars, bar tape, and saddle. Honestly, the saddle looks pretty decent;if they allowed for choosing to ship with a 148-155mm wide saddle, then Iwouldn&amp;rsquo;t have swapped it out immediately. I&amp;rsquo;m also not that perturbed by thepedals; I like SPD style and others like a variety of other styles;satisfying everyone here is impossible. But the handlebar tape isunforgivably bad. The bike should ship with some at least halfway decent tapelike the Stages bike seems to. I thought I was going to be okay with the barsand tape, but after my first five rides I took the bars to my local bike shopand had the tape replaced. It&amp;rsquo;s that bad.&lt;/li&gt;&lt;li&gt;Continuing point 2, the Kickr is more expensive than the Stages, even beforefactoring in the shipping tax. I do not understand the pricing given the corecomponents they have &amp;ldquo;cheaped out on.&amp;rdquo; I think it should cost exactly thesame as, if not a bit less than, the Stages bike so the remainder of thebudget can be spent on the upgrades they know everyone will be doing.&lt;/li&gt;&lt;li&gt;The adjustable parts, e.g. seat post, rotate in the frame. I&amp;rsquo;d much ratherthese parts be more square such that they are easier to keep aligned whiletrying to set their correct positions.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;To be clear: even though I&amp;rsquo;ve only ridden it a few times, I can tell I am goingto be happy with it and much happier than I was with the already good Kickrtrainer. The flywheel is much smoother and quieter, and the the software seemsfar more accurate to a real ride. It&amp;rsquo;s a really, &lt;em&gt;really&lt;/em&gt;, good experience.&lt;/p&gt;&lt;h3 id=&#34;an-aside&#34;&gt;  An Aside  &lt;a href=&#34;#an-aside&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;I had to contact Wahoo support about my new Kickr Bike the day after getting itsetup. As detailed in &lt;a href=&#34;https://jrfom.com/posts/2021/09/03/a-bike-crash/&#34;&gt;my previous post&lt;/a&gt;, I wasunable to setup the bike by myself due to my fractured arm. A friend helped mewith it, and I gave him the wrong pedal to put into the left crank arm. He triedtoo hard to screw the pedal in before mentioning something wasn&amp;rsquo;t right and hadtrashed the threads in the 170mm hole. I told support about all of this and theyshipped me a replacement crank arm under warranty. This was a great experiencewith their support.&lt;/p&gt;&lt;h2 id=&#34;my-real-issues-are-startup-issues&#34;&gt;  My Real Issues Are Startup Issues  &lt;a href=&#34;#my-real-issues-are-startup-issues&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Back when I first started using Wahoo products I noticed an open position ontheir site for an iOS developer. I was &lt;em&gt;very&lt;/em&gt; tempted to apply. I didn&amp;rsquo;t for tworeasons: foremost, I didn&amp;rsquo;t want to deal with the traffic driving up to thenorth side of Atlanta every day, and my iOS development skills were junior atbest (and technically still are). I suppose if I had been able to show myability to learn quickly and improve my limited skill set in the required areathat I could&amp;rsquo;ve moved closer once obtaining the job. But I&amp;rsquo;m glad I didn&amp;rsquo;t evenattempt that scenario. I think it is probably very hectic around the Wahoooffice.&lt;/p&gt;&lt;p&gt;Now that I have been working at a startup for a few years, I can see what Ithink are some rather glaring issues with Wahoo as a company. I alluded to itabove in the Bolt section. Wahoo &lt;a href=&#34;https://www.crunchbase.com/organization/wahoo-fitness&#34;&gt;as a&lt;/a&gt; &lt;a href=&#34;http://web.archive.org/web/20211020003625/https://sgbonline.com/wahoo-fitness-secures-investment/&#34;&gt;startup&lt;/a&gt; hasscaled rapidly at the cost of quality. A few examples are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;The fact that their device management software can&amp;rsquo;t synchronize data betweendevices in the same family. I can easily envision the conversation:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Engineer: &amp;quot;we are missing data synchronization between Elemnt Bolts when  people own more than one or are upgrading.&amp;quot;Project Manager: &amp;quot;we&#39;ll put it on the backlog.&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This says to me that they prioritize new features over &amp;ldquo;finishing&amp;rdquo; or&amp;ldquo;polishing&amp;rdquo; the &lt;a href=&#34;mvp&#34;&gt;MVP&lt;/a&gt; features required to ship.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Their web store can&amp;rsquo;t tie purchases to an account created during the checkoutprocess. I am certain that I created an account while buying my Bolt v2 duringcheckout. I cannot leave a review for the device on their site because theorder is not associated with my account. This is what they said when I askedwhy:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Order (redacted) does not show up under your account because you werenot logged in at the time of purchase. Unfortunately, there is no way for usto reallocate it, but if you have any issues with the order, that ordernumber, or the email that was used when it was placed will allow us to lookit up in our system.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;What this says to me is that they have implemented the features &lt;em&gt;they&lt;/em&gt; need inthe store and moved on from the &amp;ldquo;little&amp;rdquo; things that customers wouldappreciate. Again, prioritizing new features over finishing what they started.If their web store isn&amp;rsquo;t completely developed in-house, they have implementedonly the bare minimum to integrate whatever provider they chose to power it.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The Tickrs suddenly not working correctly. I can only assume it&amp;rsquo;s due tofirmware on the Bolt, as I never update the Tickrs. Still, I looked forfirmware updates for at least the v2 when it started doing the same thing andfound none.&lt;/p&gt;&lt;p&gt;As with the Bolt management software, this shows a lack of attention toreleased products and keeping them maintained.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The Kickr Bike&amp;rsquo;s build quality is clearly the first iteration a fast movingstartup would put out to get ahead of, or catch up to, the competition. WhatI see when I look at this bike is a company that said, &amp;ldquo;okay, we&amp;rsquo;ve put outall of the pieces and tested them in the market. We now need a full bike somash them all together and get an MVP out.&amp;rdquo; (All the pieces being thetrainer&amp;rsquo;s flywheel and the &amp;ldquo;climb&amp;rdquo; accessory for the trainer). Again, I dolike this bike, it&amp;rsquo;s just a real clear example of my assertion.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;This nonsense about needing an account to use the management software forthe devices like the Bolt or Bike. I am quite certain the justificationslisted are the result of some team &lt;em&gt;trying&lt;/em&gt; to come up with reasons &lt;em&gt;you&lt;/em&gt;,the user, would want yet another account. But the real reason is transparent:tying data to specific people for machine learning and marketing. There iszero reason the software would need an account to check for new firmwareupdates or send error reports (except in this case to make it easier torequest more data about the error and report a resolution).&lt;/p&gt;                                  &lt;style&gt;        .image-gallery {          display: grid;          grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));          gap: 0.5em;        }      &lt;/style&gt;          &lt;div class=&#34;image-gallery&#34;&gt;              &lt;div class=&#34;image-gallery-item&#34;&gt;                                  &lt;a href=&#34;need-account.png&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2021/10/19/wahoo-thoughts/need-account_huf9da2a3631e6562ed781640f7d9b51bc_100148_480x0_resize_q80_box_3.png&#34; /&gt;&lt;/a&gt;                  &lt;/div&gt;          &lt;/div&gt;  &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;As I said at the outset, I genuinely like Wahoo products. I just wish they wouldslow down a bit to refine them them and support them better.&lt;/p&gt;</description>
     </item>
   
     <item>
       <title>A Bicycle Crash</title>
       <link>https://jrfom.com/posts/2021/09/03/a-bike-crash/</link>
       <pubDate>Fri, 03 Sep 2021 10:00:00 -0400</pubDate>
       
       <guid>https://jrfom.com/posts/2021/09/03/a-bike-crash/</guid>
       <description>&lt;p&gt;On August 27, 2021 I drove from my house in the Atlanta, GA area to downtownPhiladelphia, PA. My goal: participate in the&lt;a href=&#34;https://web.archive.org/web/20210702214920/https://philadelphianakedbikeride.wordpress.com/2021/03/22/pnbr-12-the-mask-edition-8-28-2021/&#34;&gt;2021 Philadelphia Naked Bike Ride&lt;/a&gt;. I don&amp;rsquo;t get truly excited by manythings, but I was very excited for this event. First, it would be &lt;em&gt;way&lt;/em&gt; outsideof my normal comfort zone and a chance to expand my life experience. Second,I am extremely weary of the shame we attach to the human body as a society. Isee events like this as a way toward overcoming such inane views.&lt;/p&gt;&lt;p&gt;So drove up on Friday, had a nice leisurely morning touring some nationalmonuments, and passing time until time for the ride.&lt;/p&gt;                &lt;style&gt;      .image-gallery {        display: grid;        grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));        gap: 0.5em;      }    &lt;/style&gt;    &lt;div class=&#34;image-gallery&#34;&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;tour/IMG_3015.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2021/09/03/a-bike-crash/tour/IMG_3015_hu8e201020aade5459c7a2b39d6559bd7d_1611539_350x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;tour/IMG_3017.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2021/09/03/a-bike-crash/tour/IMG_3017_hu8e201020aade5459c7a2b39d6559bd7d_2794119_350x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;tour/IMG_3018.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2021/09/03/a-bike-crash/tour/IMG_3018_hu8e201020aade5459c7a2b39d6559bd7d_2927289_350x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;tour/IMG_3020.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2021/09/03/a-bike-crash/tour/IMG_3020_hu8e201020aade5459c7a2b39d6559bd7d_3570675_350x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;tour/IMG_3022.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2021/09/03/a-bike-crash/tour/IMG_3022_hud45366930fa00fedcca8cdb154ae06c4_2663269_350x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;tour/IMG_3023.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2021/09/03/a-bike-crash/tour/IMG_3023_hud45366930fa00fedcca8cdb154ae06c4_2991736_350x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                            &lt;a href=&#34;tour/IMG_3024.jpeg&#34;&gt;&lt;img src=&#34;https://jrfom.com/posts/2021/09/03/a-bike-crash/tour/IMG_3024_hu5acf0222c4994ac637270f38e21dfb39_2365223_350x0_resize_q80_box.jpeg&#34; /&gt;&lt;/a&gt;              &lt;/div&gt;          &lt;div class=&#34;image-gallery-item&#34;&gt;                  &lt;video controls autoplay=&#34;false&#34; width=&#34;350&#34;&gt;            &lt;source src=&#34;tour/IMG_3021.mov&#34; type=&#34;video/quicktime&#34; /&gt;          &lt;/video&gt;              &lt;/div&gt;      &lt;/div&gt;&lt;h2 id=&#34;the-crash&#34;&gt;  The Crash  &lt;a href=&#34;#the-crash&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;figure class=&#34;float-right&#34;&gt;&lt;img src=&#34;IMG_3027.jpeg&#34;/&gt;&lt;/figure&gt;&lt;p&gt;The afternoon had a few rain showers. But they passed in time for the event,at least enough that there were only occasional drops. So the streets were wet.And the streets were unfamiliar. I was biking to the event, enjoying the factthat Philadelphia has actual bike lanes along most of the thoroughfares, whenI came to an intersection where I needed to turn left. The intersection wasa large one fed by, I believe, five roads. As I was trying to get through thejunction quickly, I didn&amp;rsquo;t notice the trolly tracks in the road until I wascrossing them.&lt;/p&gt;&lt;p&gt;Disaster!&lt;/p&gt;&lt;p&gt;The still wet, and very slick, trolly tracks ripped my bike out from under me.I went down right arm and face first straight into the asphalt. One loud&lt;em&gt;crack!&lt;/em&gt; later and my weekend was over. I didn&amp;rsquo;t lose consciousness, andimmediately jumped up with enough orientation to gather my bike and self andget out of the road before cross traffic started flowing again. Some helpfulpeople across the road (sorry, I wish I had got your names and such!) rushed tomy aid and got an ambulance ordered. I spent the rest of the weekend inPresbyterian hospital in downtown Philidelphia undergoing scans and observation.&lt;/p&gt;&lt;p&gt;Result: I acquired a ~2mm subdural hematoma, several scrapes and bruises, anda fractured humerus. Once I got back home and met with local doctors I learnedthat I need to limit screen time (brain activity) for a couple weeks, and Ishouldn&amp;rsquo;t need surgery on my arm if I keep it immobilized for at least threesolid weeks. It&amp;rsquo;ll take around six to eight weeks to get back to any normalcy.&lt;/p&gt;&lt;h2 id=&#34;final-thoughts&#34;&gt;  Final Thoughts  &lt;a href=&#34;#final-thoughts&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Philidelphia is interesting. It has a lot of history, and a &lt;em&gt;lot&lt;/em&gt; ofmuseums to match, with some really nice infrastructure (at least in development).But I never felt actually safe while alone walking through it. Literally, thereare homeless on every corner dealing with varying degrees of substance abuse.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The Marriott downtown on Market and Filbert is a nice enough hotel, but theyare completely useless at compasion. When I called from my hospital bed to askwhat we could do to make my ordeal easier, since I had no way of knowing when Iwould actually be discharged from the hospital, the best they would do is extendmy checkout time to 14:00. Nevermind that they only offer valet parking on siteso I would &lt;em&gt;still&lt;/em&gt; have to figure out how to deal with the parking garage theydirected me to across the street. In short: this hotel can fuck off.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;If you need them in an emergency, there are worse hospitals you could findyourself at than Presbyterian. For reasons too difficult to get into now,though, I am quite happy to be back in Atlanta being seen by some best in theworld doctors.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;</description>
     </item>
   
     <item>
       <title>First Project With A Raspberry Pi</title>
       <link>https://jrfom.com/posts/2020/08/30/first-rpi-project/</link>
       <pubDate>Sun, 30 Aug 2020 12:35:00 -0400</pubDate>
       
       <guid>https://jrfom.com/posts/2020/08/30/first-rpi-project/</guid>
       <description>&lt;p&gt;For some time, I have been wanting to replace my self-built router with a&lt;a href=&#34;https://web.archive.org/web/20200627121804/https://www.ui.com/unifi-routing/unifi-security-gateway-pro-4/&#34;&gt;Unifi Gateway&lt;/a&gt; so that I could build a &lt;a href=&#34;https://en.wikipedia.org/wiki/Docker_(software)&#34;&gt;Docker&lt;/a&gt; server out ofthat system. Unfortunately, the Unifi Gateway continues to lack a feature Ineed: monthly bandwith usage tracking. Until it at least gains that feature,I will be sticking with &lt;a href=&#34;https://en.wikipedia.org/wiki/PfSense&#34;&gt;pfSense&lt;/a&gt;. But there are at least two thingsthat I really need a Docker server for:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Running the Unifi management app via &lt;a href=&#34;https://github.com/jacobalberty/unifi-docker&#34;&gt;https://github.com/jacobalberty/unifi-docker&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Running a &lt;a href=&#34;https://github.com/localtunnel/localtunnel&#34;&gt;localtunnel&lt;/a&gt; server&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;As I was mulling over this problem, it occurred to me that these use casesdo not require tremendous resources. So I decided to make my first projectwith a &lt;a href=&#34;https://en.wikipedia.org/wiki/Raspberry_Pi&#34;&gt;Raspberry Pi&lt;/a&gt; be a project to turn one into a Docker server.This post details my experience and setup, because it hasn&amp;rsquo;t been easy.&lt;/p&gt;&lt;h2 id=&#34;parts-list&#34;&gt;  Parts List  &lt;a href=&#34;#parts-list&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&#34;https://web.archive.org/web/20200828214703/https://www.microcenter.com/product/622539/4_Model_B_-_8GB_DDR4&#34;&gt;RPI 4 B (8GB)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://web.archive.org/web/20200828214836/https://www.microcenter.com/product/615250/64GB_Canvas_Select_Plus_MicroSDHC_Class_10-_UHS-1_Flash_Memory_Card_w-_Adapter&#34;&gt;64GB Memory Card&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://web.archive.org/web/20200828215016/https://www.microcenter.com/product/608458/6_in_34AWG_High_Speed_HDMI_Cable_With_Ethernet_Port_Saver&#34;&gt;HDMI to micro-HDMI adapter&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://web.archive.org/web/20181004095419/http://www.microcenter.com/product/461761/micro_usb_wall_charger&#34;&gt;Power cable&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://web.archive.org/web/20200828215631/https://www.microcenter.com/product/608177/Micro-HDMI_to_Standard_HDMI_(A-M),_1m_cable&#34;&gt;HDMI to micro-HDMI cable&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://web.archive.org/web/20200828215917/https://www.amazon.com/gp/product/B07XB5PR9J&#34;&gt;PoE Hat&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://web.archive.org/web/20200828220019/https://www.amazon.com/gp/product/B079J5SFYS&#34;&gt;Vesa Mount&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Not all parts in this list were useful. Keep reading for details.&lt;/p&gt;&lt;h2 id=&#34;initial-issues&#34;&gt;  Initial Issues  &lt;a href=&#34;#initial-issues&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I naively thought this would be a simple project: buy a Pi, slap an OS on it,install my stuff, and done. Not so. After getting all of my initial partstogether, I went to plug everything in and get started. Oops. The RPI4 ispowered via USB-C, not micro-USB-B. So the power cable I bought turned outto be useless and I had to return it. Resolution: power the RPI4 via a USB-Ccable connected to my laptop.&lt;/p&gt;&lt;p&gt;Now that the device is getting power, I discover my second problem: no display.I tried updating the &lt;a href=&#34;configtxt&#34;&gt;&lt;code&gt;config.txt&lt;/code&gt;&lt;/a&gt; several times to get the displayworking. Nothing helped. So I ordered a direct HDMI-to-micro-HDMI cable andput the project aside for a couple of days. After getting the cable, pluggingit in, and powering on the RPI: boom! I had a boot screen.&lt;/p&gt;&lt;h2 id=&#34;post-boot-issues&#34;&gt;  Post Boot Issues  &lt;a href=&#34;#post-boot-issues&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Now that I had a booting RPI4, I started configuring it. I used the&lt;a href=&#34;https://web.archive.org/web/2/https://www.raspberrypi.org/documentation/configuration/raspi-config.md&#34;&gt;&lt;code&gt;raspi-config&lt;/code&gt;&lt;/a&gt; tool to set all of my basic settings and rebootedthe system to find that it would not connect to my wireless network. Everythinglooked correct, but since the official RPI OS is based upon Debian, everythingwas obscurred by systemd. I did some basic log inspection, but couldn&amp;rsquo;t findany relevant error messages. So I decided to check if &lt;a href=&#34;https://voidlinux.org/&#34;&gt;Void Linux&lt;/a&gt; wouldwork. Turns out, not quite.&lt;/p&gt;&lt;p&gt;Void, at this time, only has pre-built images for the Raspberries 1, 2, and 3.They do not have an image for the RPI4. However, someone had figured out howto build such an image. So I started working on that.&lt;/p&gt;&lt;h2 id=&#34;building-a-void-linux-image&#34;&gt;  Building A Void Linux Image  &lt;a href=&#34;#building-a-void-linux-image&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The patch and instructions for building the image are at:&lt;a href=&#34;https://github.com/void-linux/void-packages/pull/23541&#34;&gt;https://github.com/void-linux/void-packages/pull/23541&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Unfortunately, Void moves fast and those instructions resulted in mergeconflicts. So here&amp;rsquo;s my tweaked instructions:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Directly clone the &lt;code&gt;void-packages&lt;/code&gt; repo.&lt;/li&gt;&lt;li&gt;Directly clone the &lt;code&gt;void-mklive&lt;/code&gt; repo.&lt;/li&gt;&lt;li&gt;Create a new branch in the &lt;code&gt;void-packages&lt;/code&gt; repo.&lt;/li&gt;&lt;li&gt;Apply the Pull Request&amp;rsquo;s changes manually since they are few.&lt;/li&gt;&lt;li&gt;Follow the rest of the instructions as printed.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;I recommend doing all of this in a virtual machine with a fresh installof Void Linux as the working environment. It is going to take a &lt;em&gt;long&lt;/em&gt; timeto complete all of this. There will be several cross compliation and buildstages.&lt;/p&gt;&lt;aside&gt;  If you trust me, you can download the image I built. But hopefully Void  will get their build process updated to include RPI4 by default. Definitely  check to see if that is case at the time of reading this before attempting  to use this image:  &lt;a href=&#34;https://keybase.pub/jsumners/rpi4/void-rpi4-20200828.img.xz&#34;&gt;    https://keybase.pub/jsumners/rpi4/void-rpi4-20200828.img.xz  &lt;/a&gt;&lt;/aside&gt;&lt;p&gt;After building the image and flashing it to the memory card, I mounted the&lt;code&gt;/boot&lt;/code&gt; FAT32 partition and replaced the &lt;code&gt;config.txt&lt;/code&gt; with the one from theofficial image:&lt;a href=&#34;https://keybase.pub/jsumners/rpi4/config.txt&#34;&gt;https://keybase.pub/jsumners/rpi4/config.txt&lt;/a&gt;.&lt;/p&gt;&lt;h2 id=&#34;void-is-live&#34;&gt;  Void Is Live!  &lt;a href=&#34;#void-is-live&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The Void based card booted (and a helluva log quicker than that systemd basednonsense, too), I edited &lt;code&gt;/etc/wpa_supplicant/wpa_supplicant.conf&lt;/code&gt; to add mynetwork configuration, enabled the &lt;code&gt;wpa_supplicant&lt;/code&gt; service, and I immediatelyhad a working wireless connection. Success!&lt;/p&gt;&lt;p&gt;First things first, resize the root partition:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;code&gt;xbps-install parted&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;parted&lt;/code&gt; and then &lt;code&gt;resizepart 2 62GB&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Quit &lt;code&gt;parted&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;resize2fs /dev/mmcblk0p2&lt;/code&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Next, try to install Docker&amp;hellip; Sadness! A pre-built package is not availble:&lt;a href=&#34;https://github.com/void-linux/void-packages/issues/18062&#34;&gt;https://github.com/void-linux/void-packages/issues/18062&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;At this point, the system was usable, but due to lack of community support, somework had to be done to get everything where I wanted it. Mostly, this just meantsetting up a build environment on the Pi so that I could build the Dockerpackages. After that, it was all normal system setup. What this meant for me,was getting the ethernet NIC configured for the IP address I wanted to give itand then mounting it in its permanent location. That way I could do theremainder of the work headless over SSH.&lt;/p&gt;</description>
     </item>
   
     <item>
       <title>A Rumination On A Promotion</title>
       <link>https://jrfom.com/posts/2020/05/19/new-title-who-dis/</link>
       <pubDate>Tue, 19 May 2020 19:35:00 -0400</pubDate>
       
       <guid>https://jrfom.com/posts/2020/05/19/new-title-who-dis/</guid>
       <description>&lt;p&gt;May 01, 2020 marked two years since I &lt;a href=&#34;https://jrfom.com/posts/2018/04/30/a-new-career/&#34;&gt;switched careers&lt;/a&gt;.That career change was from a &amp;ldquo;Linux System Adminstrator&amp;rdquo; to a &amp;ldquo;SoftwareEngineer.&amp;rdquo; Today, I was formally promoted to &amp;ldquo;Senior Software Engeineer.&amp;rdquo;So I think it is worth taking a few minutes to write down my views on whatswitching careers and gaining a new title in that new career has meant to me.&lt;/p&gt;&lt;h2 id=&#34;on-switching-careers&#34;&gt;  On Switching Careers  &lt;a href=&#34;#on-switching-careers&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Let&amp;rsquo;s cut to the quick: as I write this I&amp;rsquo;m 40 years old, and will hit 41 inthree and half short months. When I decided to give up the work I wascomfortable doing, I was four years off from the &lt;a href=&#34;https://web.archive.org/web/20200519224150/https://www.bls.gov/emp/tables/median-age-labor-force.htm&#34;&gt;median age&lt;/a&gt; forwhite men in the work force. So I was well into the typical timeframe foran adult&amp;rsquo;s working age range. Switching careers so late was a scary propositionand one I anguished over. If the position had been with any other company, I&amp;rsquo;mfairly certain I would have turned it down.&lt;/p&gt;&lt;p&gt;But having made the change, I can confidently advise people: if the change willbe to a career you know you&amp;rsquo;ll love more than what you currently do, i.e. thenew career is what you &lt;em&gt;really&lt;/em&gt; want to do, then do not hesitate. Nothingcompares to switching from a role you are competent at, and merely coasting on,to one that you genuinely enjoy doing every day. It&amp;rsquo;s worth whatever you considerto be the risks to make the change. There is a caveat, however: the careerchange may be worth it, but the destination might not be. I was extremely luckyto get recruited to where I am, but if you are not so lucky, do not let thedestination ruin it. Take that resumé improvement and roll it into anotherimprovement by finding a better organizational fit.&lt;/p&gt;&lt;h2 id=&#34;on-titles&#34;&gt;  On Titles  &lt;a href=&#34;#on-titles&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;First, a little background. The institution I left did nothing to prepare mefor how things work &amp;ldquo;in the real world.&amp;rdquo; I left a state institution whereupward mobility was, essentially, tied to moving institutions. In other words,promotions were very rare and mostly only occurred by leaving one universityto go work for another university in &lt;a href=&#34;https://www.usg.edu/&#34;&gt;the system&lt;/a&gt;. Occassionally acompensation bump would happen, but it was usually on the order of 3% and neverkept up with inflation. These things translated into not understanding one&amp;rsquo;sworth and not understanding what role titles mean to peers and potentialemployeers (because the system didn&amp;rsquo;t really care; you were just movingfrom A to B in their view).&lt;/p&gt;&lt;p&gt;So, it has taken me a while to develop some understanding of the importanceof regularly (roughly) attaining a new title. Personally, a title doesn&amp;rsquo;tconfer any special impetus upon me. I do not change how I approach my worksimply because my title is missing some qualifier. I believe, and everyoneI have spoken to concurs, that I have been operating at this &amp;ldquo;senior&amp;rdquo; levelsince day one.&lt;/p&gt;&lt;aside&gt;  &lt;p&gt;    It is understandable that I was not hired with that qualifier since    I did switch careers and could not prove on paper my ability.  &lt;/p&gt;&lt;/aside&gt;&lt;p&gt;But it has become clear to me that titles do matter:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;It gives others in the organization some idea of how you contribute to theteam. This is particularly true if the organization makes it clear how theydefine roles. A great example is &lt;a href=&#34;https://web.archive.org/web/20200519232729/https://developer.squareup.com/blog/squares-growth-framework-for-engineers-and-engineering-managers/&#34;&gt;Square&amp;rsquo;s growth framework&lt;/a&gt;.Their public spreadsheet very clearly lays out what they expect from eachperson with each respective title.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;It shows personal, professional, growth to potential employers. While Ihave no desire or expectation to ever leave my current organization, the onlyguarantee the future offers is death. So it is important to be able to showothers outside of your organization that you have been able to meet rank upthresholds. And, while they may not have as clear an insight into what thatrole means as if they were considering someone from a place like Square, theyat least have some inkling of what to expect based on industry norms.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=&#34;summary&#34;&gt;  Summary  &lt;a href=&#34;#summary&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;In short, don&amp;rsquo;t let your age or time invested in a current career stop you frompursing your true desire. And don&amp;rsquo;t let complacency or modesty hold you back.Have frank discussions with whomever you need to about what it will take torank up, and accept it when it is offered. Otherwise, you could find yourselfat a severe disadvantage when you really don&amp;rsquo;t need to be.&lt;/p&gt;</description>
     </item>
   
     <item>
       <title>Adding A Static IPv6 Address To A Void Linux Server</title>
       <link>https://jrfom.com/posts/2019/11/03/static-ipv6-void-linux/</link>
       <pubDate>Sun, 03 Nov 2019 08:40:00 -0400</pubDate>
       
       <guid>https://jrfom.com/posts/2019/11/03/static-ipv6-void-linux/</guid>
       <description>&lt;p&gt;First, a little background. At home, I am stuck with Comcast for an ISP.Probably the &lt;em&gt;only&lt;/em&gt; redeeming quality of this is that they have fully rolledout dual stack IPv4+IPv6 to all of their customers. Everyone on their networkgets personal access to more IPv6 addresses than ever existed in the wholeIPv4 space. They assign a &lt;code&gt;/128&lt;/code&gt; to your WAN interface, and from there you canrequest a &lt;code&gt;/64&lt;/code&gt;, or in my case a &lt;code&gt;/60&lt;/code&gt; to handle my multiple VLANs, for all ofyour internal devices. So, last weekend I took the time to get IPv6 enabledon my home network. Primarily to get my Xbox One X directly connected to theInternet, but also, because it was something to do.&lt;/p&gt;&lt;p&gt;This weekend, on a lark, I checked with my VPS provider, &lt;a href=&#34;https://www.vultr.com/?ref=6889759&#34;&gt;Vultr&lt;/a&gt;, to seeif they provide an IPv6 address for my server. Answer: yep! they provide a full&lt;code&gt;/64&lt;/code&gt;. The result is a couple hours of me adding IPv6 to the host that servedthis website to you and this article detailing the things I learned.&lt;/p&gt;&lt;h2 id=&#34;implementation&#34;&gt;  Implementation  &lt;a href=&#34;#implementation&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;a href=&#34;https://voidlinux.org/&#34;&gt;Void Linux&lt;/a&gt; provides a very basic plaform upon which you can buildwhatever system you like. For me, one particularly attractive aspect is thatI get to define my network configuration simply with &lt;a href=&#34;https://web.archive.org/web/20191103125931/https://docs.voidlinux.org/config/network/static.html&#34;&gt;&lt;code&gt;/etc/rc.local&lt;/code&gt;&lt;/a&gt;and the &lt;a href=&#34;https://en.wikipedia.org/wiki/Iproute2&#34;&gt;iproute2&lt;/a&gt; tools. So, while this article is techincallyspecific to Void, the information should be easily applicable to any situationwhere one is managing everything themselves instead of through higher leveltooling.&lt;/p&gt;&lt;p&gt;My previous IPv4 only &lt;code&gt;rc.local&lt;/code&gt;:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ip addr add 45.63.16.142/8 brd 45.255.255.255 scope global dev eth0&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ip link set up dev eth0&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ip route add default via 45.63.16.1 dev eth0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;My &lt;code&gt;rc.local&lt;/code&gt; after adding my IPv6 configuration:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ip addr add 45.63.16.142/8 brd 45.255.255.255 scope global dev eth0&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ip addr add 2001:19f0:5:23de:5400:00ff:fe1e:54e2/64 scope global dev eth0&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ip link set up dev eth0&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ip route add default via 45.63.16.1 dev eth0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A couple of things to notice here:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The difference is only one line: adding the IPv6 address to the interface.&lt;/li&gt;&lt;li&gt;IPv4 requires manual configuration of the gateway.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;It&amp;rsquo;s item #2 that makes things tricky. Whereas IPv4 reserves specific IPs forspecific purposes (broadcast and gateway) in each subnet, IPv6 does not. Instead,it uses the &lt;a href=&#34;https://en.wikipedia.org/wiki/Neighbor_Discovery_Protocol&#34;&gt;Neighbor Discovery Protocol&lt;/a&gt; (NDP) to advertise, and learnabout, routers available on the network. Thus, only adding an IPv6 addressto the network interface will not accomplish anything useful. We need tolisten for router advertisement messages and use them to build our routerules.&lt;/p&gt;&lt;p&gt;First, we need to be able to hear said advertisements. So we need to tweak thesystem&amp;rsquo;s firewall to allow ICMPv6 traffic:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ip6tables -I INPUT -j ACCEPT -p icmpv6&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the IPv4 world we are used to simply denying all ICMP traffic, or allowingonly very specific types of ICMP traffic. This is due to various remote attacksvia ICMP messages, but IPv6 relies on several ICMP messages to operate correctly.Thus, we allow ICMPv6 traffic to pass through our firewall. Ultimately,my &lt;code&gt;/etc/iptables/ip6tables.rules&lt;/code&gt; file looks like:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;*filter&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;:INPUT ACCEPT &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;0:0&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;:FORWARD ACCEPT &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;0:0&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;:OUTPUT ACCEPT &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;0:0&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-A INPUT -j ACCEPT -m state --state RELATED,ESTABLISHED&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-A INPUT -j ACCEPT -p tcp -m tcp --dport &lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-A INPUT -j ACCEPT -p tcp -m tcp --dport &lt;span style=&#34;color:#ae81ff&#34;&gt;443&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-A INPUT -j ACCEPT -p icmpv6&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-A INPUT -j REJECT --reject-with icmp6-adm-prohibited&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-A FORWARD -j REJECT --reject-with icmp6-adm-prohibited&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;COMMIT&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The finaly piece of this puzzle is &lt;em&gt;actually&lt;/em&gt; listening for the routeradvertisement messages. This is accomplished through the &lt;a href=&#34;https://github.com/DanielAdolfsson/ndppd&#34;&gt;ndppd&lt;/a&gt;daemon:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;code&gt;xbps-install -y ndppd&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;echo &amp;quot;proxy eth0 {}&amp;quot; &amp;gt; /etc/ndppd.conf&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;ln -s /etc/sv/ndppd /var/service&lt;/code&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Done! At this point all that is left is to update service configurationsto listen on the IPv6 address in addition to the IPv4 address. For example,the HTTP frontend in my &lt;a href=&#34;https://www.haproxy.org/&#34;&gt;HAProxy&lt;/a&gt; config required one new line:&lt;/p&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-conf&#34; data-lang=&#34;conf&#34;&gt;frontend proxy   bind 45.63.16.142:80   bind 2001:19f0:5:23de:5400:ff:fe1e:54e2:80 v6only   use_backend default-server&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Well, there is one more thing: don&amp;rsquo;t forget to add a &lt;code&gt;AAAA&lt;/code&gt; record in your DNS.&lt;/p&gt;&lt;h2 id=&#34;conclusion&#34;&gt;  Conclusion  &lt;a href=&#34;#conclusion&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Getting IPv6 enabled is really not difficult. The difficult part was trackingdown all of the information. Pretty much every article I could find assumedthe underlying distribution was already taking care of the details for you.None of them actually outlined the constituent parts those distributions useto make things work. The key was researching how router advertisements arehandled by &lt;em&gt;clients&lt;/em&gt; on an IPv6 network (routers would be using &lt;code&gt;radvd&lt;/code&gt; insteadof &lt;code&gt;ndppd&lt;/code&gt;). I hope this article clears things up for others looking to doimplement things on their own.&lt;/p&gt;</description>
     </item>
   
     <item>
       <title>Xbox One X Hard Drive Replacement</title>
       <link>https://jrfom.com/posts/2019/03/03/xbox-one-x-hd-replacement/</link>
       <pubDate>Sun, 03 Mar 2019 12:00:00 -0500</pubDate>
       
       <guid>https://jrfom.com/posts/2019/03/03/xbox-one-x-hd-replacement/</guid>
       <description>&lt;p&gt;Over the weekend a friend posted an image of an error his Xbox One X has beenthrowing at random times over the past couple of months. A quick Internet searchrevealed the likely cause to be a bad hard drive. Of course I made thesuggestion to try and get Microsoft to replace it, but I knew that the consolewas out of warranty because we both got our One X consoles at the same time(and mine is out of warranty). So I also suggested that he could replacethe hard drive by following some &lt;a href=&#34;https://www.ifixit.com/Guide/Xbox+One+Hard+Drive+Replacement/36771&#34;&gt;iFixit instructions&lt;/a&gt;. Since I detestSeagate hard drives, and SSDs were on sale, I decided to follow my own advice.&lt;/p&gt;&lt;p&gt;Unfortunately, the iFixit instructions are currently only for the original XboxOne. Their &lt;a href=&#34;https://www.ifixit.com/Device/Xbox_One_X&#34;&gt;Xbox One X page&lt;/a&gt; only has the teardown video at this time.As I got into this process I learned a few things that are worth sharing here.So the following is a basic summary of how to replace the hard drive in aXbox One X.&lt;/p&gt;&lt;h2 id=&#34;teardown&#34;&gt;  Teardown  &lt;a href=&#34;#teardown&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;It&amp;rsquo;s a generally easy process with the One X. You only need two screw driversand a little patience. All screws that need to be removed are &lt;a href=&#34;https://www.ifixit.com/Store/Tools/T9-Torx-Screwdriver/IF145-087-2&#34;&gt;Torx T9&lt;/a&gt;screws unless otherwise noted, and then they are &lt;a href=&#34;https://www.ifixit.com/Store/Tools/TR8-Torx-Security-Screwdriver/IF145-027-4&#34;&gt;Torx TR8&lt;/a&gt; screws.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;There are two screws on the back of the system to remove. One, on the right,is covered with a small &amp;ldquo;xbox&amp;rdquo; sticker that you must peal off and discard.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Push the top of the case forward (rear ports are facing you) about a quarterof an inch.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Slightly pull the left side of the top case away (to the left) from thesystem and rotate the top of the case up and to the right. The top case isheld on by some hook tabs and this process will free it from the hooks and makeit easy to remove (and replace later).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;At this point, you will need to remove two daughter cards that are screwedon to the internal housing. The screws holding the daughter boards on to thehousing are TR8 screws.&lt;a href=&#34;01-daughter.png&#34;&gt;&lt;img src=&#34;01-daughter.png&#34; alt=&#34;Daughter Board 1&#34;&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Next we need to remove the internal components from the bottom case. Thisis where the iFixit teardown video will get you into trouble. There are severalscrews that &lt;em&gt;do not&lt;/em&gt; need to be removed. At this point you only need to removethe two TR8 screws holding a ribbon cable in place (unplug the cable andgently push over to the side) and the six screws circled in blue in the followingimage. The four screws circled in green (numbered 7, 8, 9, and 10) do not needto be removed until time to take out the hard drive.&lt;a href=&#34;02-top.png&#34;&gt;&lt;img src=&#34;02-top.png&#34; alt=&#34;Daughter Board 1&#34;&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;With those screws removed you can lift the internal cage away from thebottom case and flip it over to reveal the bottom of the cage. This willhave two screws that need to be removed. They are circled in blue and labeled1 and 2 in the following image.&lt;a href=&#34;03-bottom.png&#34;&gt;&lt;img src=&#34;03-bottom.png&#34; alt=&#34;Daughter Board 1&#34;&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Now you can lift bottom half of the cage away from the top half to revealthe fan, power supply, and BD-ROM drive. We will remove the BD-ROM drive bylifting it up a little bit and then gently, but with quite some work, pullingthe data and power cables off the back of the drive.&lt;a href=&#34;04-open.png&#34;&gt;&lt;img src=&#34;04-open.png&#34; alt=&#34;Daughter Board 1&#34;&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The hard drive is now exposed and you can remove it by removing the 4green circled screws on the top half of the cage as mentioned in step 5and the power/data cables from the motherboard. Once the harddrive is free fromthe cage you can remove the four screws attaching it to its tray. This willallow you to simply pull off the cable attachment from the drive.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=&#34;cloning&#34;&gt;  Cloning  &lt;a href=&#34;#cloning&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This part will take a few hours. If you are upgrading to a larger hard drive,greater than 1&lt;acronym title=&#34;tebibyte&#34;&gt;TiB&lt;/acronym&gt;, then you will need tofollow some other instructions. I opted to do a 1:1 swap between a spinningdisk and a solid state drive. This means I merely needed to block copy theold drive onto the new drive. To do so, I put both drives in a&lt;a href=&#34;https://www.bestbuy.com/site/insignia-2-bay-hdd-docking-station/6153102.p?skuId=6153102&#34;&gt;USB 3.0 dock&lt;/a&gt; connected to my Mac Mini and used &lt;a href=&#34;https://en.wikipedia.org/wiki/Dd_(Unix)&#34;&gt;dd&lt;/a&gt;:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo dd &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/dev/rdisk4 of&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/dev/rdisk5 bs&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;4m&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;h2 id=&#34;important&#34;&gt;  Important  &lt;a href=&#34;#important&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;If you are using macOS as I did, you should use Disk Utility, GUI or CLI,to &lt;em&gt;&lt;strong&gt;unmount&lt;/strong&gt;&lt;/em&gt; all of the partitions from the Xbox drive that the OSautomatically mounted when you connected it. You should also double andtriple check that your &lt;em&gt;input&lt;/em&gt; drive (&lt;code&gt;if=&lt;/code&gt;) is the Xbox drive and youroutput drive (&lt;code&gt;of=&lt;/code&gt;) is your destination drive.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;If you are attempting this using Windows, it looks like there are several freeutilities that can accomplish the job, but I cannot make a personalrecommendation. Whatever you use, it should be doing a block-by-block copy.It should not be doing a &amp;ldquo;contents&amp;rdquo; copy.&lt;/p&gt;&lt;p&gt;Regardless of what you use to clone the original drive to the new one, it isgoing to take several hours. It took about 3 for me. Once the cloning is completejust revers all of the steps and you&amp;rsquo;ll be finished.&lt;/p&gt;</description>
     </item>
   
     <item>
       <title>A New Career</title>
       <link>https://jrfom.com/posts/2018/04/30/a-new-career/</link>
       <pubDate>Mon, 30 Apr 2018 10:00:00 -0400</pubDate>
       
       <guid>https://jrfom.com/posts/2018/04/30/a-new-career/</guid>
       <description>&lt;p&gt;&lt;img src=&#34;thehub.jpg#float-right&#34; alt=&#34;The HUB paperweight&#34;&gt;In 1999 I started work at &lt;a href=&#34;http://clayton.edu&#34;&gt;Clayton State University&lt;/a&gt; asa student employee. I turned my self-developed troubleshooting skills into aa job at the university&amp;rsquo;s help desk: &lt;a href=&#34;http://www.clayton.edu/hub&#34;&gt;The HUB&lt;/a&gt;.After a few years I moved over to the networking department, ostensibly tohelp build out and test the wireless network. After graduation, I was broughtback as a full-time employee in the enterprise applications department to supportvarious backend systems. This role grew into a systems administration rolewherein I was ultimately responsible for the extensive Red Hat Enterprise Linuxinfrastructure as the campus&amp;rsquo;s sole Linux administrator. At the same time, I wasresponsible for developing and maintaing the university&amp;rsquo;s student web portal.All the while, I spent my free time working on open source software as a hobby.That hobby has turned into a new career. Tomorrow I start my new role as asoftware engineer at &lt;a href=&#34;https://knock.com&#34;&gt;Knock.com&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I am genuinely exicited about my path forward. I get to work with some reallysmart people and help to grow a company that I think is going to be a majorforce for change in the real estate industry. I truly enjoy writing softwarethat people love to use. And being a part of the team that develops the platformpeople will use to make their next home purchase and sale easier will be aunique experience.&lt;/p&gt;&lt;p&gt;This post has primarily been about marking the occasion for myself. But I alsowant to thank the people who moved me foward at Clayton State University:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Debye Baird: thank you for taking a chance on the guy that was always hangingout in the public area of The HUB.&lt;/li&gt;&lt;li&gt;Dan Newcombe: thank you for finding a spot on your team for me.&lt;/li&gt;&lt;li&gt;Tom Marshall: thank you for brining me on full time.&lt;/li&gt;&lt;li&gt;Jason Berry: thank you for trusting in my skills and doing what you couldto keep me around.&lt;/li&gt;&lt;/ul&gt;</description>
     </item>
   
     <item>
       <title>My Fastify Story</title>
       <link>https://jrfom.com/posts/2018/03/07/fastify-story/</link>
       <pubDate>Wed, 07 Mar 2018 10:40:00 -0500</pubDate>
       
       <guid>https://jrfom.com/posts/2018/03/07/fastify-story/</guid>
       <description>&lt;p&gt;On 02 May 2016 I submitted my &lt;a href=&#34;https://github.com/pinojs/pino/commit/3a6ae328a9a47538608180574149dad57b4bd4ae&#34;&gt;first pull request&lt;/a&gt; (PR) to the&lt;a href=&#34;https://getpino.io/&#34;&gt;Pino&lt;/a&gt; logging library project. Subsequent PRs eventually led to me beingoffered a contributorship to the Pino project. Since then I have come to considerthe inventors of Pino, &lt;a href=&#34;https://twitter.com/davidmarkclem&#34;&gt;David Mark Clements&lt;/a&gt; and &lt;a href=&#34;https://twitter.com/matteocollina&#34;&gt;Matteo Collina&lt;/a&gt;,to be friends. Additionally, I follow their open source work since they areextremely smart individuals and produce some fantastic projects. This all ledme to &lt;a href=&#34;https://fastify.io/&#34;&gt;Fastify&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;In January of 2017 I noticed Matteo contributing to a project named Fastify.It was an intriguing name, so I investigated it. What I found was a fledglingHTTP framework. At the time, I was a big proponent of &lt;a href=&#34;https://hapijs.com/&#34;&gt;Hapi&lt;/a&gt;, a wellestablished HTTP framework. I had chosen Hapi over &lt;a href=&#34;https://expressjs.com/&#34;&gt;Express&lt;/a&gt; a fewyears ago because there was too much boilerplate in starting up a basicExpress project. Express relies on plugins for everything, even the most basicof things, whereas Hapi included a few things like form body parsing by default.Also, I just liked the way Hapi&amp;rsquo;s API worked over Express&amp;rsquo;s and Hapi&amp;rsquo;sdocumentation was more comprehensive for newbies. So, I wasn&amp;rsquo;t really lookingfor a new HTTP framework. Thus, I fired off a simple PR to &lt;a href=&#34;https://github.com/fastify/fastify/commit/d3c62668226fd4e78abb24a9e8c15d92fe467223&#34;&gt;fix a link&lt;/a&gt;to Pino&amp;rsquo;s documentation and idly paid attention to the project.&lt;/p&gt;&lt;p&gt;Over the next few months I started testing out Fastify in some small projectsat work. I simply needed to build some simple JSON only APIs and that&amp;rsquo;s whatFastify was designed to do. As I got into Fastify I started to really like itand started contributing more patches to solve some issues I was having. As timepassed I was once again asked if I would like to join the team and I consented.&lt;/p&gt;&lt;p&gt;At this time I was already writing all of my new projects against Fastify, butI had no inclination to convert old Hapi based projects to Fastify. I washappy to continue using Hapi. Then Hapi announced a &lt;a href=&#34;https://github.com/hapijs/hapi/issues/3658&#34;&gt;major overhaul&lt;/a&gt;of their framework. This was at least the second time Hapi had institutedmajorly breaking changes since I had starting using it, and this time the changesturned Hapi into a completely new framework as far as I could tell. At thispoint I dropped my support for Hapi and went all in with Fastify.&lt;/p&gt;&lt;p&gt;I had already been &lt;a href=&#34;https://github.com/fastify/fastify/issues/229&#34;&gt;pushing for Fastify v1.0.0&lt;/a&gt; to be released, butI picked up the pace at this point by requesting deadlines and more activelytraging PRs. I also started writing more plugins and patches in my free time.As of 06 March 2018 Fastify v1.0.0 has been released and I can start releasingthings like &lt;a href=&#34;https://github.com/jscas&#34;&gt;JSCAS&lt;/a&gt; as production ready with Fastify as their base.&lt;/p&gt;&lt;h2 id=&#34;what-makes-fastify-different&#34;&gt;  What Makes Fastify Different?  &lt;a href=&#34;#what-makes-fastify-different&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Fastify takes inspiration from both Express and Hapi. One of the ways in whichFastify is similar to Express is in the way it needs extra plugins to add inbasic functionality, e.g. &lt;a href=&#34;https://npm.im/fastify-formbody&#34;&gt;fastify-formbody&lt;/a&gt;. But it also emulatesHapi&amp;rsquo;s core routing API with its &lt;a href=&#34;https://www.fastify.io/docs/latest/Routes/&#34;&gt;route method&lt;/a&gt;; and this wasa bigger factor in using Hapi of Express, to be honest. So -1 and +1 and nowinner between the two to make Fastify a more attractive option.&lt;/p&gt;&lt;p&gt;No, the &lt;em&gt;real&lt;/em&gt; reason to use Fastify is its &amp;ldquo;killer features&amp;rdquo;: encapsulationand decorators. Everything in Fastify, even the routes, are &lt;a href=&#34;https://www.fastify.io/docs/latest/Plugins/&#34;&gt;a plugin&lt;/a&gt;.And each plugin is provided &lt;em&gt;its own instance&lt;/em&gt; of Fastify to work with. Thismakes it possible to write very well defined code that is easily testable.&lt;/p&gt;&lt;p&gt;Let&amp;rsquo;s consider an example. Suppose you want to have an unauthenticated welcomepage on the route &lt;code&gt;/&lt;/code&gt; and an authenticated user page on &lt;code&gt;/info&lt;/code&gt;. We could writethe following:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;fastify&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;fastify&amp;#39;&lt;/span&gt;)()&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;slashPlugin&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;fastify&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;options&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;next&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;fastify&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;get&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;request&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;reply&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;reply&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;type&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;text/html&amp;#39;&lt;/span&gt;).&lt;span style=&#34;color:#a6e22e&#34;&gt;send&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;lt;h1&amp;gt;Welcome&amp;lt;/h1&amp;gt;&amp;#39;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  })&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;infoPlugin&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;fastify&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;options&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;next&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;fastify&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;register&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;fastify-bearer-auth&amp;#39;&lt;/span&gt;), {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;keys&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Set&lt;/span&gt;([&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;123456&amp;#39;&lt;/span&gt;])&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  })&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;fastify&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;get&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/info&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;request&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;reply&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// default type: application/json&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;reply&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;send&lt;/span&gt;({&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#a6e22e&#34;&gt;username&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#a6e22e&#34;&gt;phone&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;555-555-5555&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    })&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  })&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;fastify&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  .&lt;span style=&#34;color:#a6e22e&#34;&gt;register&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;slashPlugin&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  .&lt;span style=&#34;color:#a6e22e&#34;&gt;register&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;infoPlugin&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  .&lt;span style=&#34;color:#a6e22e&#34;&gt;listen&lt;/span&gt;(&lt;span style=&#34;color:#ae81ff&#34;&gt;3000&lt;/span&gt;, (&lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt;) =&amp;gt; {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;throw&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  })&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;&lt;code&gt;slashPlugin&lt;/code&gt; and &lt;code&gt;infoPlugin&lt;/code&gt; could easily be written in separate files.&lt;/li&gt;&lt;li&gt;&lt;code&gt;slashPlugin&lt;/code&gt; and &lt;code&gt;infoPlugin&lt;/code&gt; do not have any &lt;em&gt;direct&lt;/em&gt; dependency onFastify itself. Each of these plugins can be tested without ever installingthe Fastify library.&lt;/li&gt;&lt;li&gt;&lt;code&gt;/&lt;/code&gt; has absolutely no knowledge of the &lt;code&gt;fastify-bearer-auth&lt;/code&gt; plugin andthat plugin will not have any impact on the &lt;code&gt;/&lt;/code&gt; route.&lt;/li&gt;&lt;li&gt;&lt;code&gt;/info&lt;/code&gt; will be guarded by the &lt;code&gt;fastify-bearer-auth&lt;/code&gt; plugin by virtueof the fact that the plugin is registered within its encapsulation context.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;So that&amp;rsquo;s the encapsulation feature in a nutshell. But what about decorators?Let&amp;rsquo;s assume we need to pull the user information from a MongoDB database andextend the example:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;fastify&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;fastify&amp;#39;&lt;/span&gt;)()&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;slashPlugin&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;fastify&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;options&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;next&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;fastify&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;get&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;request&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;reply&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;reply&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;type&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;text/html&amp;#39;&lt;/span&gt;).&lt;span style=&#34;color:#a6e22e&#34;&gt;send&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;lt;h1&amp;gt;Welcome&amp;lt;/h1&amp;gt;&amp;#39;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  })&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;infoPlugin&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;fastify&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;options&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;next&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;fastify&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;register&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;fastify-bearer-auth&amp;#39;&lt;/span&gt;), {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;keys&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Set&lt;/span&gt;([&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;123456&amp;#39;&lt;/span&gt;])&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  })&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;fastify&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;get&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/info&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;async&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;request&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;reply&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;db&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;fastify&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;mongo&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;db&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;users&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;await&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;db&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;collection&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;users&amp;#39;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;reply&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;send&lt;/span&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;await&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;users&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;findOne&lt;/span&gt;({&lt;span style=&#34;color:#a6e22e&#34;&gt;username&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;})&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    )&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  })&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;fastify&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  .&lt;span style=&#34;color:#a6e22e&#34;&gt;register&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;fastify-mongodb&amp;#39;&lt;/span&gt;), {&lt;span style=&#34;color:#a6e22e&#34;&gt;url&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;mongodb://localhost/foo&amp;#39;&lt;/span&gt;})&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  .&lt;span style=&#34;color:#a6e22e&#34;&gt;register&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;slashPlugin&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  .&lt;span style=&#34;color:#a6e22e&#34;&gt;register&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;infoPlugin&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  .&lt;span style=&#34;color:#a6e22e&#34;&gt;listen&lt;/span&gt;(&lt;span style=&#34;color:#ae81ff&#34;&gt;3000&lt;/span&gt;, (&lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt;) =&amp;gt; {&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;throw&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  })&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Notice that we registered &lt;code&gt;fastify-mongodb&lt;/code&gt; on the root instance of Fastify.By virtue of &lt;a href=&#34;https://npm.im/fastify-plugin&#34;&gt;fastify-plugin&lt;/a&gt;, which &lt;code&gt;fastify-mongodb&lt;/code&gt; uses,we are able to access the &lt;code&gt;mongo&lt;/code&gt; decorator that the plugin adds within anyplugin registered within the same context. Since &lt;code&gt;slashPlugin&lt;/code&gt; and &lt;code&gt;infoPlugin&lt;/code&gt;are also registered to the root Fastify context, the &lt;code&gt;mongo&lt;/code&gt; decorator isavailable to them.&lt;/p&gt;&lt;p&gt;Hopefully you can see how powerful the combination of decorators andencapsulation are. They radically changed how I develop JSCAS, for the better.As an example, the plugin API in JSCAS has been completely redesigned and&lt;a href=&#34;https://github.com/jscas/cas-server/blob/261099ce78bc7f51e6f9298b3301ec9cc525efb0/lib/plugins/pluginApiPlugin.js&#34;&gt;implemented&lt;/a&gt; via these Fastify features. I think you&amp;rsquo;ll find themas awesome as I do if you start using them.&lt;/p&gt;&lt;h2 id=&#34;fin&#34;&gt;  Fin  &lt;a href=&#34;#fin&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I am very happy to have been a part of getting Fastify v1.0.0 ready for release.I think it has the potential to radically impact the way HTTP servers arewritten in Node.js. It&amp;rsquo;s &lt;em&gt;fast&lt;/em&gt; and introduces concepts that greatly simplifiescode and promotes modularity. I look forward to seeing the community and projectgrow.&lt;/p&gt;</description>
     </item>
   
     <item>
       <title>Sugar</title>
       <link>https://jrfom.com/posts/2017/12/29/sugar/</link>
       <pubDate>Fri, 29 Dec 2017 18:45:00 -0500</pubDate>
       
       <guid>https://jrfom.com/posts/2017/12/29/sugar/</guid>
       <description>&lt;p&gt;Around the middle of May this year (2017) I was browsing through my&lt;a href=&#34;https://netflix.com&#34;&gt;Netflix&lt;/a&gt; recommendations when I came across a documentarycalled &lt;a href=&#34;http://www.imdb.com/title/tt3892434/&#34;&gt;&lt;em&gt;That Sugar Film&lt;/em&gt;&lt;/a&gt;. I decided to watch it. It is not anexaggeration to say that film changed me; at least since then and for theforeseeable future. After watching that film I spent the remainder of the monthfinishing off every food item in my house that contained added sugar. On 01 June2017 I stopped consuming &lt;em&gt;anything&lt;/em&gt; that contained added sugar for two months.At the start of those two months my weight fluctuated between 205 and 210pounds. At the end of those two months I weighed about 180 pounds. The &lt;em&gt;only&lt;/em&gt;thing I changed was to stop consuming added sugar. My diet was still terrible(and arguably still is), and I wasn&amp;rsquo;t able to ride my bicycle nearly as oftenas I would have like because of rain.&lt;/p&gt;&lt;p&gt;This is what my weight measurements look like for the past year:&lt;/p&gt;&lt;p&gt;&lt;img src=&#34;bp_weight_history.png&#34; alt=&#34;Weight History&#34;&gt;&lt;/p&gt;&lt;p&gt;Let&amp;rsquo;s backtrack a little bit.&lt;/p&gt;&lt;p&gt;On 26 May 2014 I bought a &lt;a href=&#34;https://web.archive.org/web/20170602121334/http://archive.trekbikes.com/us/en/2014/Trek/7_2_fx&#34;&gt;new bicycle&lt;/a&gt;. I have ridden that bicyclealmost every warm day since. My typical summer ride is almost 20 miles. I do notcoast. I peddle the whole time. The elevation change over my typical ride isaround 1,200 feet, and I average 13 miles per hour. That translates to a lot ofhills and a very respectable speed for the type of bicycle. I am getting asignificant amount of exercise over this ride. Given that information, examinethis chart of my weight between 2016-03-01 and 2016-09-30:&lt;/p&gt;&lt;p&gt;&lt;img src=&#34;2016-03-01_to_2016-09-30_weight_chart.png&#34; alt=&#34;2016 Weight Chart&#34;&gt;&lt;/p&gt;&lt;p&gt;Bearing in mind that I had a couple of gout flare ups that sidelined me for afew weeks, and that I do not ride in the rain (unless I&amp;rsquo;m caught out), thething to notice about that chart is this: my weight remained fairly steadyat around 205 pounds, creeping up toward my maximum at the end of the season(due to less activity). This shows that no matter the amount of exercise I wasgetting, my weight remained roughly constant. The general belief is that, ceterisparibus, more exercise equates to less body weight (ultimately). This is clearlynot necessarily true.&lt;/p&gt;&lt;p&gt;Now consider the following graph over the same time period only one year later:&lt;/p&gt;&lt;p&gt;&lt;img src=&#34;2017-03-02_to_2017-09-29_weight_chart.png&#34; alt=&#34;2017 Weight Chart&#34;&gt;&lt;/p&gt;&lt;p&gt;Again, rain and injury are factors, but the only actual change is the eliminationof added sugar from my diet. As someone living in the South, I continued to eatridiculous amounts of fried foods, breads, and very few &amp;ldquo;healthy&amp;rdquo; foods. Actually,that&amp;rsquo;s not quite true. In late August and all of September I was unable to ridemy bicycle due to campaigning for public office (I lost). So I wasn&amp;rsquo;t gettinganywhere &lt;em&gt;near&lt;/em&gt; the same amount of exercise as the previous summer.&lt;/p&gt;&lt;h2 id=&#34;what-i-have-learned&#34;&gt;  What I Have Learned  &lt;a href=&#34;#what-i-have-learned&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;First, there are multiple forms of &amp;ldquo;sugar&amp;rdquo; that can be added to foods. The bigones are: refined cane sugar, honey, and corn syrup. Both cane sugar (&amp;ldquo;tablesugar&amp;rdquo;) and honey are 50% glucose and 50% fructose (with honey this is a roughfigure). With corn syrup it&amp;rsquo;s most likely going to be &amp;ldquo;high fructose&amp;rdquo; cornsyrup; but it&amp;rsquo;s also very likely you&amp;rsquo;ll find &lt;strong&gt;both&lt;/strong&gt; regular corn syrup andhigh fructose corn syrup in an item.&lt;/p&gt;&lt;p&gt;Second, fructose is metabolized by the body much differently from glucose.Wikipedia has &lt;a href=&#34;https://en.wikipedia.org/wiki/Fructose#Fructose_metabolism&#34;&gt;some information on the subject&lt;/a&gt;, but here&amp;rsquo;s whatmy aunt (an &lt;a href=&#34;epidemiologist&#34;&gt;epidemiologist&lt;/a&gt;) has to say about it:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;In a diet of naturally occurring fruits &amp;amp; vegetables, there will still be asubstantial amount of fructose. Both glucose &amp;amp; fructose are absorbed directlyinto the bloodstream from the gut, but fructose must be metabolized by theliver to be used as energy. The metabolites of fructose can then be used toproduce either glycogen (the storage form of glucose) or fattyacids/triglycerides (fat storage).&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;Both glucose &amp;amp; fatty acids are used as energy sources, but glucose easilycrosses the blood-brain barrier &amp;amp; is the most important source of energy forall cells. Fructose metabolism down the pathway to glycogen probably dominateswhen calorie intake is consistently in line with one&amp;rsquo;s requirements, since itwill be used to maintain glycogen stores in the liver. However, in the typicalWestern diet with excesses of calories &amp;amp; fructose, the pathway towardstriglycerides will predominate. (That&amp;rsquo;s why people with high levels oftriglycerides are advised to cut sugar intake.)&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;That was in response to my asking her opinion on this video:&lt;/p&gt;&lt;style&gt;  .embed-container { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; } .embed-container iframe, .embed-container object, .embed-container embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }&lt;/style&gt;&lt;div class=&#39;embed-container&#39;&gt;  &lt;iframe src=&#39;https://www.youtube.com/embed/f_4Q9Iv7_Ao&#39; frameborder=&#39;0&#39; allowfullscreen&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p&gt;Third, sugar is added to &lt;em&gt;everything&lt;/em&gt;. Wheat Thins™? Yep, added sugar. &amp;ldquo;Healthy&amp;rdquo;baked apple chips? Added sugar. Sliced deli meat? Almost every one of them &amp;ndash;added sugar.&lt;/p&gt;&lt;h2 id=&#34;conclusion&#34;&gt;  Conclusion  &lt;a href=&#34;#conclusion&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;By removing added sugar from my diet I have been able to bring my sugar intakedown to a &amp;ldquo;natural&amp;rdquo; level. It has forced me to prepare more of my own meals,and, in turn, learn how to make them. By doing this day-in and day-out, I amable to have a candy bar every once in a while, or a decadent desert when outfor dinner with friends. And the sugar is oh so much sweeter when I do have it.&lt;/p&gt;&lt;p&gt;If you want to try this for yourself, and don&amp;rsquo;t want to figure it all out onyour own like I did (I&amp;rsquo;m not following a specific diet), there are plenty ofresources on the Internet. For example, there&amp;rsquo;s &lt;a href=&#34;iquit&#34;&gt;iquitsugar.com&lt;/a&gt; &amp;ndash; a sitewith many good articles and a diet plan you can buy into. But it&amp;rsquo;s really notdifficult. If you follow these guidelines, you&amp;rsquo;ll never turn back:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Start on the first day of a month, and go &lt;strong&gt;completely without added sugar&lt;/strong&gt;for at least one month, if not two.&lt;/li&gt;&lt;li&gt;Setup a camera on a tripod and take a full body picture of yourself on dayone, and the last day of every month thereafter (including the first month).This picture needs to hold nothing back. Wear only what you were born in.Compare these pictures side-by-side and be amazed.&lt;/li&gt;&lt;li&gt;Plan ahead. Figure out what meals you can make yourself that don&amp;rsquo;t requireadded sugar, or that can do without the added sugar, prior to starting. Learnwhere you can eat out. If you ask places for ingredient lists, they will givethem to you.&lt;/li&gt;&lt;li&gt;Always read the labels. If you don&amp;rsquo;t recognize the words, you probablyshouldn&amp;rsquo;t eat it. The &amp;ldquo;organic&amp;rdquo; label foods are usually sugar free, e.g.Newman&amp;rsquo;s Own &amp;ldquo;Sockarooni&amp;rdquo; pasta sauce has added sugar, but the organic versiondoes not.&lt;/li&gt;&lt;li&gt;Switch to sourdough bread. Real sourdough doesn&amp;rsquo;t have added sugar.&lt;/li&gt;&lt;li&gt;Look up sugar free recipes on the Internet. Skip the ones that use sugarsubstitutes, e.g Stevia. Use some sort of fruit to sweeten foods. My favoriteis pineapple.&lt;/li&gt;&lt;/ol&gt;</description>
     </item>
   
     <item>
       <title>Starting Oracle 12c With Systemd</title>
       <link>https://jrfom.com/posts/2017/05/05/starting-oracle-12c-with-systemd/</link>
       <pubDate>Fri, 05 May 2017 15:15:00 -0400</pubDate>
       
       <guid>https://jrfom.com/posts/2017/05/05/starting-oracle-12c-with-systemd/</guid>
       <description>&lt;p&gt;I have put off migrating to RHEL 7 at work for just about as long as I quitepossibly can. The reason? The shit show known as &lt;a href=&#34;http://without-systemd.org/wiki/index.php/Arguments_against_systemd&#34;&gt;systemd&lt;/a&gt;. But thetime draws near that RHEL 6 will be EOLed, so I have begun migrating in earnest.Part of that migration is a rather important Oracle database server. SinceI like being able to start and stop things via the system service manager,I needed make it so Oracle can be started and stopped via systemd. Some basicsearching will yield some very basic service files; basic enough that I&amp;rsquo;msurprised anyone would rely upon them. So, since neither Oracle nor Red Hathave deigned to solve this problem, I have done it. This post is a descriptionof how I did so.&lt;/p&gt;&lt;p&gt;First, the Oracle database does not provide a foreground running mode. Sothat immediately complicates matters. Second, there are actually two parts tothe database service: a &amp;ldquo;listener&amp;rdquo; for client connections and the actualdatabase server. So at a minimum we need two systemd services. However, a singledatabase server can host multiple databases, or &amp;ldquo;SID&amp;quot;s in Oracle parlance. Thus,we need &lt;code&gt;n&lt;/code&gt; services for &lt;code&gt;n&lt;/code&gt; SIDs.&lt;/p&gt;&lt;h2 id=&#34;listener&#34;&gt;  Listener  &lt;a href=&#34;#listener&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Let&amp;rsquo;s tackle the listener first. For this service we will need three components:a start script, a stop script, and the service file.&lt;/p&gt;&lt;p&gt;Note: all scripts in this article are &lt;a href=&#34;http://docs.ansible.com/&#34;&gt;Ansible&lt;/a&gt; templated. Which meanswhen you see something like &lt;code&gt;{{oracle_home}}&lt;/code&gt; you should substitute a valuethat corresponds to your environment. To be clear: &lt;em&gt;&lt;strong&gt;you cannot simply copyand paste these scripts&lt;/strong&gt;&lt;/em&gt;. You must review them and adjust them for yourown environment.&lt;/p&gt;&lt;h3 id=&#34;usrlocalbinlsnrstart&#34;&gt;  &lt;code&gt;/usr/local/bin/lsnrstart&lt;/code&gt;  &lt;a href=&#34;#usrlocalbinlsnrstart&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/bash&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# {{ansible_managed}}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;runner&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;whoami&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;runner&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; !&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;oracle&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;must run as the oracle user&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  exit &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_HOME&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; -f lsnr.pid &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  curPid&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;cat lsnr.pid&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  pidIsPresent&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;ps -p &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;curPid&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;pidIsPresent&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; -eq &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    lsnrPid&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;ps uax | grep tnslsnr | grep -v -m &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; grep | awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $2}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;curPid&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;lsnrPid&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;already running&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      exit &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;# must be from an old process&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  rm -f lsnr.pid&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./bin/lsnrctl start&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;exitCode&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;$?&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;exitCode&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; -eq &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  lsnrPid&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;ps uax | grep tnslsnr | grep -v -m &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; grep | awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $2}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  echo &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;lsnrPid&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; &amp;gt; lsnr.pid&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  exit &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  exit &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;exitCode&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;usrbinlocallsnrstop&#34;&gt;  &lt;code&gt;/usr/bin/local/lsnrstop&lt;/code&gt;  &lt;a href=&#34;#usrbinlocallsnrstop&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/bash&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# {{ansible_managed}}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;runner&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;whoami&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;runner&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; !&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;oracle&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;must run as the oracle user&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  exit &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_HOME&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; -f lsnr.pid &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  curPid&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;cat lsnr.pid&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ps -p &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;curPid&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; &amp;gt; /dev/null&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; $? -eq &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    lsnrPid&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;ps uax | grep tnslsnr | grep -v -m &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; grep | awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $2}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;curPid&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;lsnrPid&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      ./bin/lsnrctl stop&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  rm -rf lsnr.pid&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;etcsystemdsystemoracle-listenerservice&#34;&gt;  &lt;code&gt;/etc/systemd/system/oracle-listener.service&lt;/code&gt;  &lt;a href=&#34;#etcsystemdsystemoracle-listenerservice&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# {{ansible_managed}}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;[Unit]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Description&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;Oracle Database Listener&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;After&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;syslog.target network.target&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;[Service]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;LimitMEMLOCK&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;infinity&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;LimitNOFILE&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{{snofile}}:{{hnofile}}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;LimitNPROC&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{{snproc}}:{{hnproc}}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;LimitSTACK&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{{sstack}}K:{{hstack}}K&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Type&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;forking&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;PIDFile&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{{oracle_home}}/lsnr.pid&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;User&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;oracle&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Group&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;oinstall&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Environment&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ORACLE_HOME={{oracle_home}}&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Environment&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ORACLE_BASE=/opt/oracle&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Environment&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;LD_LIBRARY_PATH={{oracle_home}}/ctx/lib:{{oracle_home}}/lib&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;ExecStart&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/usr/local/bin/lsnrstart&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;ExecStop&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/usr/local/bin/lsnrstop&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;TimeoutStartSec&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;30&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;TimeoutStopSec&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;60&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Restart&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;always&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;RestartSec&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;database-service&#34;&gt;  Database Service  &lt;a href=&#34;#database-service&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The database service is significantly more complicated. We need components:parent service, template service, start script and stop script. The complicatedbits are 1) the relationship between the &amp;ldquo;parent service&amp;rdquo; and the&amp;ldquo;template service&amp;rdquo; and 2) actually starting and stopping database SIDs.&lt;/p&gt;&lt;p&gt;Buried in the &lt;a href=&#34;https://www.freedesktop.org/software/systemd/man/systemd.unit.html&#34;&gt;description of unit files&lt;/a&gt; is this tidbit:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Optionally, units may be instantiated from a template file at runtime. Thisallows creation of multiple units from a single configuration file. If systemdlooks for a unit configuration file, it will first search for the literal unitname in the file system. If that yields no success and the unit name containsan &amp;ldquo;@&amp;rdquo; character, systemd will look for a unit template that shares the samename but with the instance string (i.e. the part between the &amp;ldquo;@&amp;rdquo; character andthe suffix) removed. Example: if a service &lt;a href=&#34;mailto:getty@tty3.service&#34;&gt;getty@tty3.service&lt;/a&gt; is requested andno file by that name is found, systemd will look for getty@.service andinstantiate a service from that configuration file if it is found.&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;To refer to the instance string from within the configuration file you may usethe special &amp;ldquo;%i&amp;rdquo; specifier in many of the configuration options. &amp;hellip;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;We can take advantage of this by defining an empty &amp;ldquo;parent&amp;rdquo; service that willstart and stop all of the real SID services. Thus, we will have the followingstructure:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;code&gt;/etc/systemd/system/oracle.service&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;/etc/systemd/system/oracle@.service&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;/etc/systemd/system/oracle.service.wants&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;/etc/systemd/system/oracle.service.wants/oracle@some_sid.service&lt;/code&gt; &amp;ndash; thisis a symlink back to &lt;code&gt;/etc/systemd/system/oracle@.service&lt;/code&gt;. It should be repeatedfor each SID your server serves.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The next difficult bit is that Oracle 12c is started via &lt;code&gt;sqlplus&lt;/code&gt; and notsome dedicated binary. So I had to deconstruct the &lt;code&gt;dbstart&lt;/code&gt; and &lt;code&gt;dbshut&lt;/code&gt;scripts Oracle ships to figure out exactly how to start individual instances;the shipped scripts start or stop all defined SIDs at once.&lt;/p&gt;&lt;h3 id=&#34;usrlocalbindbstart&#34;&gt;  &lt;code&gt;/usr/local/bin/dbstart&lt;/code&gt;  &lt;a href=&#34;#usrlocalbindbstart&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/bash&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# {{ansible_managed}}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;runner&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;whoami&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;runner&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; !&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;oracle&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;must run as the oracle user&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  exit &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_HOME&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;INST&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;1&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PMON&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ora_pmon_&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;INST&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SQLDBA&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_HOME&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/bin/sqlplus /nolog&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; -z &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;INST&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;must supply instance (SID) as first parameter&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  exit &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ORATAB&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/etc/oratab&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; ! -e &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORATAB&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORATAB&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; not found&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  exit &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Process oratab to see if the supplied instance should even be started&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# and setup some environment if so&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; read LINE&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;LINE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; in&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ae81ff&#34;&gt;\#&lt;/span&gt;*&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; ;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    *&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      ORACLE_SID&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;echo &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;LINE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; | awk -F: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $1}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_SID&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; !&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;INST&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;continue&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      IS_Y&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;echo &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;LINE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; | awk -F: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $NF}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;IS_Y&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; !&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Y&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;oratab indicates to skip, not starting&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;# create the pid file to keep systemd happy&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        touch db_&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_SID&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;.pid&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;# exit 255 so that we can use `Restart=on-failure`&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        exit &lt;span style=&#34;color:#ae81ff&#34;&gt;255&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      ORACLE_HOME&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;echo &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;LINE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; | awk -F: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $2}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      PATH&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_HOME&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;/bin:/bin:/usr/bin:/etc:&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;PATH&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      LD_LIBRARY_PATH&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_HOME&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;/lib:&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;LD_LIBRARY_PATH&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      export ORACLE_HOME&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      export ORACLE_SID&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      export PATH&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      export LD_LIBRARY_PATH&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      PFILE&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_HOME&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/dbs/init&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_SID&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;.ora&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      SPFILE&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_HOME&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/dbs/spfile&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_SID&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;.ora&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      SPFILE1&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_HOME&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/dbs/spfile.ora&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      break&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      ;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;esac&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;done&lt;/span&gt; &amp;lt; &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORATAB&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; -f &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_HOME&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;/dbs/sgadef&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_SID&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;.dbf -o -f &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_HOME&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;/dbs/sgadef&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_SID&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;.ora &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  echo -e &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;connect / as sysdba\nshutdown abort\nquit&amp;#34;&lt;/span&gt; | &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;SQLDBA&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; $? -ne &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;failed to stop previous instance, aborting&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    exit &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PIDFILE&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;db_&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_SID&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;.pid&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; -f &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;PIDFILE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  curPid&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;cat &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;PIDFILE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; ! -z &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;curPid&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pidIsPresent&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;ps -p &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;curPid&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;pidIsPresent&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; -eq &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      dbPid&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;ps uax | grep &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;PMON&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; | grep -v -m &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; grep | awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $2}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;curPid&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;dbPid&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;already running&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        exit &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;# must be from an old process&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  rm -f &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;PIDFILE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; -e &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;PFILE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; -o -e &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;SPFILE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; -o -e &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;SPFILE1&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  echo -e &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;connect / as sysdba\nstartup\nquit&amp;#34;&lt;/span&gt; | &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;SQLDBA&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  exitCode&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;$?&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;exitCode&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; -eq &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    dbPid&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;ps uax | grep &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;PMON&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; | grep -v -m &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; grep | awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $2}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; -z &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;dbPid&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;failed to start &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_SID&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;, could not find &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;PMON&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; pid&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      exit &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    echo &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;dbPid&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; &amp;gt; &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;PIDFILE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    exit &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;failed to start &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_SID&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    exit &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;exitCode&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;no init file found for &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_SID&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;, not starting&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  exit &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;usrlocalbindbstop&#34;&gt;  &lt;code&gt;/usr/local/bin/dbstop&lt;/code&gt;  &lt;a href=&#34;#usrlocalbindbstop&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/bash&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# {{ansible_managed}}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;runner&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;whoami&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;runner&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; !&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;oracle&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;must run as the oracle user&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  exit &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_HOME&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;INST&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;1&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PMON&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ora_pmon_&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;INST&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SQLDBA&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_HOME&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/bin/sqlplus /nolog&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; -z &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;INST&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;must supply instance (SID) as first parameter&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  exit &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ORATAB&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/etc/oratab&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; ! -e &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORATAB&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORATAB&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; not found&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  exit &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Process oratab to see if the supplied instance should even be stopped&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# and setup some environment if so&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; read LINE&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;LINE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; in&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ae81ff&#34;&gt;\#&lt;/span&gt;*&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; ;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    *&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      ORACLE_SID&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;echo &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;LINE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; | awk -F: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $1}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_SID&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; !&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;INST&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;continue&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      IS_Y&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;echo &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;LINE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; | awk -F: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $NF}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;IS_Y&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; !&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Y&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;oratab indicates to skip, not stopping&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        exit &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      ORACLE_HOME&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;echo &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;LINE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; | awk -F: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $2}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      PATH&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_HOME&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;/bin:/bin:/usr/bin:/etc:&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;PATH&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      LD_LIBRARY_PATH&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_HOME&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;/lib:&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;LD_LIBRARY_PATH&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      export ORACLE_HOME&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      export ORACLE_SID&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      export PATH&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      export LD_LIBRARY_PATH&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      break&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      ;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;esac&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;done&lt;/span&gt; &amp;lt; &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORATAB&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PIDFILE&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;db_&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;ORACLE_SID&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;.pid&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; -f &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;PIDFILE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  curPid&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;cat &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;PIDFILE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ps -p &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;curPid&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; &amp;gt; /dev/null&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; $? -eq &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    dbPid&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;ps uax | grep &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;PMON&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; | grep -v -m &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; grep | awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $2}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;curPid&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;dbPid&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      echo -e &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;connect / as sysdba\nshutdown immediate\nquit&amp;#34;&lt;/span&gt; | &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;SQLDBA&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; $? -ne &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;shutdown failed, exiting&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        exit &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  rm -f &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;PIDFILE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;etcsystemdsystemoracleservice&#34;&gt;  &lt;code&gt;/etc/systemd/system/oracle.service&lt;/code&gt;  &lt;a href=&#34;#etcsystemdsystemoracleservice&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# {{ansible_managed}}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;[Unit]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Description&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;Oracle Database 12c&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;After&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;oracle-listener.service&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# This non-service merely exists so that database instances managed&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# via oracle@.service can all be started/stopped at the same time.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;[Service]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Type&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;oneshot&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;RemainAfterExit&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;yes&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;ExecStart&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/bin/bash -c &amp;#39;echo &amp;#34;starting oracle database service&amp;#34;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;etcsystemdsystemoracleservice-1&#34;&gt;  &lt;code&gt;/etc/systemd/system/oracle@.service&lt;/code&gt;  &lt;a href=&#34;#etcsystemdsystemoracleservice-1&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# {{ansible_managed}}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;[Unit]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Description&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;Oracle Database instance %I&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;BindTo&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;oracle.service&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;After&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;oracle.service&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;[Install]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;WantedBy&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;oracle.service&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;[Service]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;LimitMEMLOCK&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;infinity&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;LimitNOFILE&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{{snofile}}:{{hnofile}}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;LimitNPROC&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{{snproc}}:{{hnproc}}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;LimitSTACK&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{{sstack}}K:{{hstack}}K&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Type&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;forking&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;PIDFile&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{{oracle_home}}/db_%I.pid&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;User&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;oracle&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Group&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;oinstall&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Environment&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ORACLE_HOME={{oracle_home}}&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Environment&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ORACLE_BASE=/opt/oracle&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;ExecStart&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/usr/local/bin/dbstart %I&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;ExecStop&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/usr/local/bin/dbstop %I&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;TimeoutStartSec&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;30&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;TimeoutStopSec&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;60&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Despite the following, disabled SIDs will continually try to restart.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# I suspect it&amp;#39;s because shitstemd is confused by being told a PID file will&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# exist, but no usable such file can be generated since no process will be&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# started. Of course, the documentation makes it sound like this will work.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Restart&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;on-failure&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;RestartSec&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;RestartPreventExitStatus&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;255&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;SucessExitStatus&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;0 255&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
     </item>
   
     <item>
       <title>A Primer On Contributing To Projects With Git</title>
       <link>https://jrfom.com/posts/2017/03/08/a-primer-on-contributing-to-projects-with-git/</link>
       <pubDate>Wed, 08 Mar 2017 14:10:00 -0500</pubDate>
       
       <guid>https://jrfom.com/posts/2017/03/08/a-primer-on-contributing-to-projects-with-git/</guid>
       <description>&lt;p&gt;There isn&amp;rsquo;t any shortage of tutorials on this subject, but I haven&amp;rsquo;t seen anythat attempt to guide a person that has zero experience with any of it. So,the goal of this article is to give a fresh &amp;ldquo;newbie&amp;rdquo; all of the informationthey need to collaborate on projects that use the &lt;a href=&#34;https://git-scm.com/&#34;&gt;Git SCM&lt;/a&gt;. This will notbe a complete, or even a full introductory, guide to &lt;em&gt;git&lt;/em&gt;; you should readother tutorials, and the &lt;a href=&#34;https://git-scm.com/docs&#34;&gt;reference docs&lt;/a&gt; for that.&lt;/p&gt;&lt;p&gt;&lt;a id=&#34;setup&#34;&gt;&lt;/a&gt;&lt;/p&gt;&lt;h2 id=&#34;setup&#34;&gt;  Setup  &lt;a href=&#34;#setup&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;We will focus on using the command line interface. Thus, to start, we needto setup the environment.&lt;/p&gt;&lt;p&gt;&lt;a id=&#34;windows&#34;&gt;&lt;/a&gt;&lt;/p&gt;&lt;h3 id=&#34;windows&#34;&gt;  Windows  &lt;a href=&#34;#windows&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;I am not a Windows person. My day job is a Linux administrator and my full-timedesktop environment is Appple macOS. Given that, the easiest environment I havefound for Windows is to:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Install &lt;a href=&#34;https://git-for-windows.github.io/&#34;&gt;msysgit&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Install &lt;a href=&#34;https://conemu.github.io/&#34;&gt;ConEmu&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Configure the default &amp;ldquo;task&amp;rdquo; for ConEmu to the one that uses the Bashshell provided by msysgit&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;a id=&#34;linux&#34;&gt;&lt;/a&gt;&lt;/p&gt;&lt;h3 id=&#34;linux&#34;&gt;  Linux  &lt;a href=&#34;#linux&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;This will vary based on the distribution you use. The short of it is that youneed to install their package that provides &lt;em&gt;git&lt;/em&gt;; typically, the name of thepackage is simply &amp;ldquo;git&amp;rdquo;.&lt;/p&gt;&lt;p&gt;If you are using &lt;a href=&#34;https://voidlinux.eu&#34;&gt;Void Linux&lt;/a&gt; (my preference), then Irecommend installing both the &amp;ldquo;git&amp;rdquo; and &amp;ldquo;git-perl&amp;rdquo; packages.&lt;/p&gt;&lt;p&gt;&lt;a id=&#34;macos&#34;&gt;&lt;/a&gt;&lt;/p&gt;&lt;h3 id=&#34;macos&#34;&gt;  macOS  &lt;a href=&#34;#macos&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;I prefer using the &amp;ldquo;git&amp;rdquo; package from &lt;a href=&#34;https://www.macports.org/&#34;&gt;MacPorts&lt;/a&gt;.But the easiest way to get started is to simply open a Terminal.app sessionand execute &lt;code&gt;git&lt;/code&gt;:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ &lt;span style=&#34;color:#75715e&#34;&gt;# you will be prompted to install the necessary components&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Speaking of Terminal.app, I recommend switching to &lt;a href=&#34;http://iterm2.com/&#34;&gt;iTerm2&lt;/a&gt;.It&amp;rsquo;s just better.&lt;/p&gt;&lt;h3 id=&#34;config&#34;&gt;  Config  &lt;a href=&#34;#config&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;With &lt;em&gt;git&lt;/em&gt; installed, you should now configure it to know some details aboutyou. These details will be used to identify you on the changes that youmake within a project:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git config --global user.name &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;FirstName Surname&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git config --global user.email &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;your.email@example.com&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a id=&#34;authentication&#34;&gt;&lt;/a&gt;&lt;/p&gt;&lt;h3 id=&#34;authentication&#34;&gt;  Authentication  &lt;a href=&#34;#authentication&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;We will discuss central repositories shortly, but regardless of how the projectyou wish to contribute to chooses to centralize, you will need to authenticateyourself when synchronizing your contributions. You have two options:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Communicate with the central repositories over HTTPS&lt;/li&gt;&lt;li&gt;Communicate with the central repositories over SSH&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;In case #1, you will be prompted for your user credentials each time youwork with the remote system. You can minimize this by using a &amp;ldquo;credential helper.&amp;rdquo;A nice overview of getting such a helper setup is available at&lt;a href=&#34;http://stackoverflow.com/a/5343146/7979&#34;&gt;http://stackoverflow.com/a/5343146/7979&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;As for case #2, you will need to create an SSH key pair for yourself and configurethe remote system to recognize it. Given the complexity of this method, we willassume the first method is being used. If you want to learn about the SSH method,then I am sure whichever central system your project uses will have instructionsthat will help you out.&lt;/p&gt;&lt;p&gt;&lt;a id=&#34;collaboration&#34;&gt;&lt;/a&gt;&lt;/p&gt;&lt;h2 id=&#34;collaboration&#34;&gt;  Collaboration  &lt;a href=&#34;#collaboration&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Now that we have a working &lt;em&gt;git&lt;/em&gt; environment, we can learn about how to actuallyuse it to collaborate on a project.&lt;/p&gt;&lt;p&gt;&lt;a id=&#34;account-setup&#34;&gt;&lt;/a&gt;&lt;/p&gt;&lt;h3 id=&#34;account-setup&#34;&gt;  Account Setup  &lt;a href=&#34;#account-setup&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Whether you are working solely within an institution or you are participatingin an open source project, you will be working with a central repository.There are many ways a repository can be hosted centrally, but the most common,and the ones we will assume in this article, are provided by thefollowing services:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;a href=&#34;https://github.com&#34;&gt;GitHub&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://gitlab.com&#34;&gt;GitLab&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://bitbucket.org&#34;&gt;Bitbucket&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;All three offer some form of on-premises solution, public hosted repositories,and private hosted repositories. Regardless of the service provider and itslocation, you will need an account with the service. Thus, the easiest stepis the first &amp;ndash; create an account.&lt;/p&gt;&lt;p&gt;For the rest of this article we will assume you created a GitHub account at&lt;a href=&#34;https://github.com&#34;&gt;github.com&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;a id=&#34;git-and-github&#34;&gt;&lt;/a&gt;&lt;/p&gt;&lt;h3 id=&#34;git-and-github&#34;&gt;  Git And GitHub  &lt;a href=&#34;#git-and-github&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;em&gt;git&lt;/em&gt; is a distributed source code management tool. This means that &lt;em&gt;git&lt;/em&gt; isintended to be used locally, &lt;em&gt;without&lt;/em&gt; a central server. But all of the sitesoutlined in &lt;a href=&#34;#account-setup&#34;&gt;account setup&lt;/a&gt; are centralized server. So we needto think of sites like GitHub as a system that many people have &amp;ldquo;local&amp;rdquo; accountson where they store their &lt;em&gt;git&lt;/em&gt; repositories. This allows the users to make theirrepositories available to other users of the GitHub system, such that thoseusers can create their own copy of other users&amp;rsquo;s repositories. In turn, thisallows GitHub to provide features on top of the standard &lt;em&gt;git&lt;/em&gt; features.&lt;/p&gt;&lt;p&gt;As a brief overview of the remainder of this article, the workflow createdby this setup is as follows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Bob creates a &lt;em&gt;git&lt;/em&gt; repository on his local machine.&lt;/li&gt;&lt;li&gt;Bob copies it to his GitHub account, thus making the real respository theone hosted on the GitHub system.&lt;/li&gt;&lt;li&gt;Alice decides she likes Bob&amp;rsquo;s project and wants to help him with it, so she&amp;ldquo;forks&amp;rdquo; (copies) the repository to her own GitHub account.&lt;/li&gt;&lt;li&gt;Alice &amp;ldquo;clones&amp;rdquo; her copy of the repository on the GitHub system to her localcomputer.&lt;/li&gt;&lt;li&gt;Alice tells her local repository about Bob&amp;rsquo;s &amp;ldquo;upstream&amp;rdquo; (original)repository so that she can stay up-to-date with Bob&amp;rsquo;s changes.&lt;/li&gt;&lt;li&gt;Alice creates a &amp;ldquo;branch&amp;rdquo; on her local repository, makes changes, and &amp;ldquo;pushes&amp;rdquo;those changes to her fork on the GitHub system.&lt;/li&gt;&lt;li&gt;Alice uses the GitHub interface to tell Bob about her changes, asking if he&amp;rsquo;dlike to incorprate them into his original repository.&lt;/li&gt;&lt;li&gt;Bob decides he likes the changes, accepts them, and his repository on thethe GitHub system is updated.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;a id=&#34;forking&#34;&gt;&lt;/a&gt;&lt;/p&gt;&lt;h3 id=&#34;fork-the-project&#34;&gt;  Fork The Project  &lt;a href=&#34;#fork-the-project&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;For remainder of this article we will assume that you want to collaborate on theawesome &lt;a href=&#34;https://github.com/pinojs/pino&#34;&gt;Pino&lt;/a&gt; project. Our first step is tocreate a copy of the project in our account on GitHub. So we navigate to[https://github.com/pinojs/pino] in a web browser and click &amp;ldquo;Fork&amp;rdquo; button(currently in the upper right corner of the page). GitHub will then show ascreen that the process is happening, and then load the Pino repositoryin your account.&lt;/p&gt;&lt;p&gt;&lt;a id=&#34;cloning&#34;&gt;&lt;/a&gt;&lt;/p&gt;&lt;h3 id=&#34;cloning&#34;&gt;  Cloning  &lt;a href=&#34;#cloning&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Now that Pino has been forked to your account, we will &amp;ldquo;clone&amp;rdquo; it to yourlocal machine. Cloning, in this context, is merely copying the repositoryfrom your GitHub account to your personal computer. To accomplish this task,we use our terminal and enter:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ cd ~/Projects &lt;span style=&#34;color:#75715e&#34;&gt;# or any place you want to keep a collection of projects&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git clone https://github.com/your-username/pino.git&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At this point you will have a directory: &lt;code&gt;~/Projects/pino&lt;/code&gt;. This directoryis your local copy of the repository. This local copy is automatically tied toyour copy of the repository on the GitHub system. This link between your twocopies is known locally by the name &amp;ldquo;origin&amp;rdquo;. Within &lt;em&gt;git&lt;/em&gt; this is known asa &amp;ldquo;remote&amp;rdquo;. To see the remotes associated with your local repository, which,at this point, is only &amp;ldquo;origin&amp;rdquo;, issue the commands:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ cd ~/Projects/pino&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git remote&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For more information on remotes, read&lt;a href=&#34;https://git-scm.com/docs/git-remote&#34;&gt;https://git-scm.com/docs/git-remote&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;a id=&#34;upstream&#34;&gt;&lt;/a&gt;&lt;/p&gt;&lt;h3 id=&#34;link-to-upstream&#34;&gt;  Link To Upstream  &lt;a href=&#34;#link-to-upstream&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Before you begin working on your changes it is a good idea to connect yourlocal repository to the original repository. Colloquially, this is knownas the &amp;ldquo;upstream&amp;rdquo; remote. From within your local repository, issue thefollowing command:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git remote add upstream https://github.com/pinojs/pino.git&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a id=&#34;branching&#34;&gt;&lt;/a&gt;&lt;/p&gt;&lt;h3 id=&#34;create-a-feature-branch&#34;&gt;  Create A Feature Branch  &lt;a href=&#34;#create-a-feature-branch&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;We are now ready to begin working on some changes to the project. The key tosuccessful collaboration is to request the minimal amount of changes as isnecessary to implement your idea (or fix). You should do this on a new branchwithin your repository. A branch is merely a snapshot of the repository at aspecific point in time. By working on a branch you lock the project to thestate at which you decided you want to add changes, and it makes it easierfor the upstream project owners to review your changes when you submit them.&lt;/p&gt;&lt;p&gt;Typically, you will want to name your branch in such a way that it indicateswhy the branch was created. So, let&amp;rsquo;s assume we want to make some documentationcorrections. Enter the following command from within your local copy of therepository:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git checkout -b doc-corrections&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above command is a shortcut for the following two commands:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git branch doc-corrections&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git checkout doc-corrections&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Every repository has what is known as a &lt;code&gt;master&lt;/code&gt; branch. At this point, wehave started a new branch, &lt;code&gt;doc-corrections&lt;/code&gt; from the current state of the&lt;code&gt;master&lt;/code&gt; branch. To see the branches available:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git branch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Before moving on, let&amp;rsquo;s also create the &lt;code&gt;doc-corrections&lt;/code&gt; branch within yourcopy of the repository on GitHub. To do this, we will &amp;ldquo;push&amp;rdquo; our branch:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git push -u origin doc-corrections&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This has done two things:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;It has created the &lt;code&gt;doc-corrections&lt;/code&gt; branch in your repository on GitHub.&lt;/li&gt;&lt;li&gt;It has configured your local copy of the repository to know that the local&lt;code&gt;doc-corrections&lt;/code&gt; corresponds to the &lt;code&gt;doc-corrections&lt;/code&gt; in your GitHub copyof the repository. This allows for some shortcuts when issuing certain&lt;em&gt;git&lt;/em&gt; commands.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;To learn more about branching and pushing, see:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&#34;https://git-scm.com/docs/git-branch&#34;&gt;https://git-scm.com/docs/git-branch&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;https://git-scm.com/docs/git-push&#34;&gt;https://git-scm.com/docs/git-push&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&#34;making-changes&#34;&gt;  Making Changes  &lt;a href=&#34;#making-changes&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Now that we are on our own branch we can make our changes. For now, let&amp;rsquo;spretend you have made some typo corrections to the &lt;code&gt;README.md&lt;/code&gt; file. Which isto say, you have opened &lt;code&gt;README.md&lt;/code&gt; in your text editor, adjusted the textwithin and saved the document. If you issue the following command:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git status&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You will see that &lt;em&gt;git&lt;/em&gt; has recognized that you made changes to the file. Atthis point &lt;em&gt;git&lt;/em&gt; isn&amp;rsquo;t going to do anything with those changes. Files thatare tracked by a &lt;em&gt;git&lt;/em&gt; repository have two stages: modified and scheduledto be committed. In the &amp;ldquo;modified&amp;rdquo; state &lt;em&gt;git&lt;/em&gt; merely recognizes that a filehas been changed from its initial state. In the &amp;ldquo;scheduled to be committed&amp;rdquo;state &lt;em&gt;git&lt;/em&gt; will write the changes made to the file into its internal trackingwhen the &lt;code&gt;git commit&lt;/code&gt; command is run. So, let&amp;rsquo;s move our changes from themodified state to the schedule state:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git add README.md&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With the changes scheduled to be committed, let&amp;rsquo;s actually perform the commit:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git commit -m &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;A short summary of the changes&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above is the equivalent of sending an email with nothing more than thesubject line filled in. To write a full commit message, simply issue&lt;code&gt;git commit&lt;/code&gt;. This will open the default commit editor, probably a variantof &lt;code&gt;vi&lt;/code&gt;. A full commit message should have the following format:&lt;/p&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;A short summary of the changesA body describing in further detail your changes.The summary line should not exceed 40 to 50 characters, and the bodylines should not exceed 80 characters. Thes are not hard and fastrules, per se, but they widely followed guidelines.Some projects have other requirements for commit messages, andmay refuse changes if they are not followed.&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With your changes committed to the local repository, it&amp;rsquo;s time to send themto your copy on GitHub:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git push&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We are able to use this short push command since we linked your local&lt;code&gt;doc-corrections&lt;/code&gt; branch to your remote &lt;code&gt;doc-corrections&lt;/code&gt; branch. If we hadn&amp;rsquo;t,you&amp;rsquo;d have to issue:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git push origin doc-corrections&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can learn more about committing at&lt;a href=&#34;https://git-scm.com/docs/git-commit&#34;&gt;https://git-scm.com/docs/git-commit&lt;/a&gt;.&lt;/p&gt;&lt;h3 id=&#34;incorporating-upstream-changes&#34;&gt;  Incorporating Upstream Changes  &lt;a href=&#34;#incorporating-upstream-changes&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Prior to sending our corrections to the upstream project, it&amp;rsquo;s a good ideato make sure you have any changes that have occurred upstream into yourrepository. To do that, we need to switch to the &lt;code&gt;master&lt;/code&gt; branch, pull inchanges from upstream, and then merge them into your &lt;code&gt;doc-corrections&lt;/code&gt;branch:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git checkout master&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git pull upstream master&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git checkout doc-corrections&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git merge master&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At this point &lt;em&gt;git&lt;/em&gt; may tell you that there are conflicts. A conflict ariseswhen the same file has been edited in both branches of the merge,&lt;code&gt;master&lt;/code&gt; and &lt;code&gt;doc-corrections&lt;/code&gt; in this case, such that &lt;em&gt;git&lt;/em&gt; can&amp;rsquo;t decidewhich change should &amp;ldquo;win.&amp;rdquo; If this happens you will need to fix the conflictsand then issue a &lt;code&gt;git commit&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;With all of the changes incorporated, it&amp;rsquo;s time to push them to your copyon GitHub: &lt;code&gt;git push&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;You can learn more about resolving conflicts at&lt;a href=&#34;https://githowto.com/resolving_conflicts&#34;&gt;https://githowto.com/resolving_conflicts&lt;/a&gt;.&lt;/p&gt;&lt;h3 id=&#34;sending-your-changes-to-upstream&#34;&gt;  Sending Your Changes To Upstream  &lt;a href=&#34;#sending-your-changes-to-upstream&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Now that your changes are pushed to your copy of the repository on GitHub, it&amp;rsquo;stime to send them to the upstream repository owner(s) for review and possibleinclusion. To do this, open your copy of the repository on GitHub. It&amp;rsquo;ll be ata URL like &lt;code&gt;https://github.com/your-username/pino&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;With your repository open on GitHub in your browser, you should see a messagesuggesting that you send a &amp;ldquo;Pull Request&amp;rdquo; (PR) from your &lt;code&gt;doc-corrections&lt;/code&gt;branch to the upstream &lt;code&gt;master&lt;/code&gt; branch. Simply click the button in that messageand you&amp;rsquo;ll be taken to a form where you will can describe your PR. It willdefault to the last commit message in your branch, but you can change it.When you are happy with the PR message, submit the PR and wait.&lt;/p&gt;&lt;p&gt;GitHub is going to email the authors of the upstream project to let them knowabout your PR. They will review it and probably start a discussion with you, orjust accept it if a discussion isn&amp;rsquo;t necessary. Either way, you will receiveemails keeping you informed of the process.&lt;/p&gt;&lt;p&gt;Once the PR has been resolved, you can remove your feature branch:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git checkout master&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git pull upstream master&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git branch -D doc-corrections&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;summary&#34;&gt;  Summary  &lt;a href=&#34;#summary&#34; class=&#34;heading-link&#34;&gt;§&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;While it may seem like a complicated process, and in some ways it is, you shouldnow be able to collaborate on a project that uses the Git SCM. In general, thisis how most open source projects work. And once you have gone from fork toPR, the process shortens to simply staying synchronized, creating branches, andsubmitting PRs.&lt;/p&gt;&lt;p&gt;Don&amp;rsquo;t be afraid to get involved. If the upstream people ask for changes, in mostcases they are not insinuating anything about you personally. The simply wantyour changes to conform to the nature of their project so that your changes canbe included. Or they have suggestions for improvement, so that your changes canbe included.&lt;/p&gt;&lt;p&gt;A great place to get started with almost any project is with the documentation,just as we did in this article. If there&amp;rsquo;s one thing every project wants it&amp;rsquo;ssomeone willing to write documentation. As you get more comfortable, you willcertainly start branching out from there.&lt;/p&gt;&lt;p&gt;By the way, I&amp;rsquo;m a maintainer on the &lt;a href=&#34;https://github.com/pinojs/pino&#34;&gt;Pino&lt;/a&gt;project. I look forward to seeing your PRs :)&lt;/p&gt;</description>
     </item>
   
     <item>
       <title>Switching To Void Linux On My HTPC</title>
       <link>https://jrfom.com/posts/2016/01/10/switching-to-void-linux-on-my-htpc/</link>
       <pubDate>Sun, 10 Jan 2016 17:15:00 -0500</pubDate>
       
       <guid>https://jrfom.com/posts/2016/01/10/switching-to-void-linux-on-my-htpc/</guid>
       <description>&lt;p&gt;In 2008 I built myself a &lt;a href=&#34;https://en.wikipedia.org/wiki/Home_theater_PC&#34;&gt;HTPC&lt;/a&gt;. It started out running&lt;a href=&#34;https://www.archlinux.org/&#34;&gt;Arch Linux&lt;/a&gt; but switched to &lt;a href=&#34;http://www.ubuntu.com/&#34;&gt;Ubuntu&lt;/a&gt; when Arch decided to forcesystemd. Ubuntu&amp;rsquo;s &lt;a href=&#34;http://upstart.ubuntu.com/&#34;&gt;Upstart&lt;/a&gt; didn&amp;rsquo;t live up to Arch&amp;rsquo;s original RCsystem, but it fit the bill of &lt;em&gt;not&lt;/em&gt; being systemd. I have never liked Ubuntuso it was most certainly a stop-gap solution. My replacement for Ubuntu is&lt;a href=&#34;http://www.voidlinux.eu/&#34;&gt;Void Linux&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I discovered Void a few months ago when &lt;a href=&#34;https://www.debian.org/&#34;&gt;Debian&lt;/a&gt; decided to forcesystemd as well. Once that happened I did &lt;a href=&#34;http://distrowatch.com/search.php?pkg=systemd&amp;amp;pkgver=&amp;amp;distrorange=NotInLatest#pkgsearch&#34;&gt;some digging&lt;/a&gt; on&lt;a href=&#34;http://distrowatch.com/&#34;&gt;Distrowatch&lt;/a&gt; for distributions that didn&amp;rsquo;t include systemd (aside:technicall I did a search for distros with a specific init system, but thatdoesn&amp;rsquo;t seem possible at the time of this writing). After researching a few onthe list it was clear to me that Void Linux would be my new distribution ofchoice. The release model is very much like Arch&amp;rsquo;s, makes a point of &lt;em&gt;not&lt;/em&gt; using&lt;a href=&#34;https://en.wikipedia.org/wiki/OpenSSL&#34;&gt;OpenSSL&lt;/a&gt; by using &lt;a href=&#34;https://en.wikipedia.org/wiki/LibreSSL&#34;&gt;LibreSSL&lt;/a&gt; instead, and uses&lt;a href=&#34;http://smarden.org/runit/&#34;&gt;Runit&lt;/a&gt; for the init system.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Regarding LibreSSL over OpenSSL: look back at the early posts of&lt;a href=&#34;http://opensslrampage.org/&#34;&gt;opensslrampage.org&lt;/a&gt;. &lt;a href=&#34;http://opensslrampage.org/post/96025631325/does-sslcipherdescription-return-an-allocated&#34;&gt;It&amp;rsquo;s&lt;/a&gt; &lt;a href=&#34;http://opensslrampage.org/post/91771553861/kill-optimism-in-docs&#34;&gt;very&lt;/a&gt; &lt;a href=&#34;http://www.openbsd.org/papers/eurobsdcon2014-libressl.html&#34;&gt;illuminating&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Runit is rather amazing in its simplicity. The flexibility of systemvinit isstill present, but there&amp;rsquo;s pretty much no reason to have more than 5 linesin a Runit init script; still, there are &lt;a href=&#34;https://bitbucket.org/avery_payne/supervision-scripts/wiki/Home&#34;&gt;crazy people&lt;/a&gt; out there. Theshort of it is Runit doesn&amp;rsquo;t fork processes. It simply starts a process andwaits for it to exit. If the process does exit, Runit restarts. So a completeinit script can be:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/sh&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;mkdir -p /run/samba&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;exec smbd -F -S&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That simple script is all that is necessary to start &lt;a href=&#34;https://www.samba.org/&#34;&gt;Samba&lt;/a&gt;. Comparethat to a traditional sysv &lt;a href=&#34;http://pkgs.fedoraproject.org/cgit/rpms/samba.git/tree/smb.init?h=f16&#34;&gt;init script&lt;/a&gt; or a &lt;a href=&#34;http://pkgs.fedoraproject.org/cgit/rpms/samba.git/tree/smb.service?id=3d3cbc8a73664be88a2ca7e9af5dfcde1778722d&#34;&gt;systemd script&lt;/a&gt;and you&amp;rsquo;ll see why this is so great.&lt;/p&gt;&lt;p&gt;So, getting back to my HTPC. Reinstalling the base OS with Void was very easy.And installing everything I needed to run my interface (&lt;a href=&#34;http://kodi.tv/&#34;&gt;Kodi&lt;/a&gt;) waseven easier:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ xbps-install kodi xorg x11vnc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, at this point there&amp;rsquo;s always some trickery needed to get the system toboot straight to Kodi. This time was no exception. Initially I thought I&amp;rsquo;d beable to get by with &lt;a href=&#34;https://wiki.voidlinux.eu/Automatic_Login_to_Graphical_Environment&#34;&gt;a guide&lt;/a&gt; on the Void wiki. But that didn&amp;rsquo;t pan out:the guide assumes the user will only ever be used for logging in straightto X11. I need to SSH to the system as that user on a regular basis, so thatassumption wouldn&amp;rsquo;t work.&lt;/p&gt;&lt;p&gt;When I originally built my HTPC back in 2008 there was a &lt;a href=&#34;https://en.wikipedia.org/wiki/X_display_manager_(program_type)&#34;&gt;display manager&lt;/a&gt;that supported automatic logins without much hassle (I can&amp;rsquo;t recall which one).But that got replaced with &lt;a href=&#34;https://en.wikipedia.org/wiki/SLiM&#34;&gt;SLiM&lt;/a&gt;. SLiM supported automatic logins, butonly on the &lt;em&gt;first&lt;/em&gt; login. If whatever program you were running, Kodi in thiscase, crashed then you&amp;rsquo;d be staring at login screen. Who wants to get out akeyboard and mouse to use an entertainment system? Not me. I searched fora solution and found none, so I wrote my own tool for the job. If you&amp;rsquo;ve readthis site for a while you may have seen it listed as &amp;ldquo;mythlogin&amp;rdquo;, as Ioriginally used &lt;a href=&#34;https://www.mythtv.org/&#34;&gt;MythTV&lt;/a&gt;. Since the guide&amp;rsquo;s method of automatic loginwouldn&amp;rsquo;t work for me I once again turned to my tool. This time I&amp;rsquo;ve renamedit &lt;a href=&#34;https://github.com/jsumners/autox&#34;&gt;autox&lt;/a&gt;; this tool will be in the official Void respository likelyby the time you read this.&lt;/p&gt;&lt;p&gt;I originally wrote &lt;em&gt;autox&lt;/em&gt; to be used on a sysvinit system with an&lt;a href=&#34;http://linux.die.net/man/5/inittab&#34;&gt;inittab&lt;/a&gt;. When I switched to Ubuntu it turned out using &lt;em&gt;autox&lt;/em&gt; wasalmost just as easy. But under Runit? It wasn&amp;rsquo;t so easy:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;autox doesn&amp;rsquo;t &lt;em&gt;truly&lt;/em&gt; log a user in to the system. It merely sets up hisregular environment with all of his &lt;a href=&#34;https://en.wikipedia.org/wiki/Linux_PAM&#34;&gt;PAM&lt;/a&gt; granted permissions, e.g.real-time clock access.&lt;/li&gt;&lt;li&gt;simply using &lt;a href=&#34;http://linux.die.net/man/8/agetty&#34;&gt;agetty&lt;/a&gt; as the guide does results in the process beinglaunched outside of Runit&amp;rsquo;s supervisor proccess. That&amp;rsquo;s no good since wewant Runit to manage the process.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Digging in to how Void sets up ttys I learned about a tool I hadn&amp;rsquo;t heard ofbefore &amp;ndash; &lt;a href=&#34;http://man7.org/linux/man-pages/man1/setsid.1.html&#34;&gt;setsid&lt;/a&gt;. Combining &lt;code&gt;setsid&lt;/code&gt; with &lt;code&gt;agetty&lt;/code&gt; did the trick.The resulting Runit script for my HTPC:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/sh&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sv start wpa_supplicant&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;exec 2&amp;gt;&amp;amp;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;exec setsid -w agetty -a htpc -n -l /usr/bin/autox -o htpc tty7 &lt;span style=&#34;color:#ae81ff&#34;&gt;38400&lt;/span&gt; linux&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Wait. What is line number three? That&amp;rsquo;s how you define a dependent serviceunder Runit. Instead of some convoluted descriptor file like Upstart andsystemd want you just start the required service. In this case I need networkaccess and my HTPC is only connected via 802.11n currently. So I need toauthenticate to my access point prior to launching Kodi since Kodi uses theInternet.&lt;/p&gt;&lt;p&gt;There was one other problem, though. I use x11vnc to make X11 accessible frommy other computers. This is handy when I need to do something with Kodi thatwould be a chore with just an IR remote. I had been using my &lt;code&gt;.xinitrc&lt;/code&gt; fileto launch x11vnc. I was using &lt;code&gt;exec&lt;/code&gt; to fork it off into its own process inthe background. Well, do that under this new configuration resulted in x11vncrunning outside of Runit&amp;rsquo;s supervisor process. Again, not good. Solution?Runit:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/sh&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;sv start kodi&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;exec x11vnc -many -q -avahi -ncache &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt; -passwd super_secret&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Again, since x11vnc is dependent on X11 being already up and running I justinvoke the &lt;code&gt;kodi&lt;/code&gt; service before hand. Simple.&lt;/p&gt;&lt;p&gt;Finally, there is one other piece of my HTPC puzzle. I use &lt;a href=&#34;http://nzbget.net/&#34;&gt;nzbget&lt;/a&gt;for some things. And I let it run on my HTPC as the &amp;ldquo;htpc&amp;rdquo; user. Under theprevious init systems it wasn&amp;rsquo;t worth the hassle to define it as a systemservice. So I wrapped it in a &lt;a href=&#34;https://en.wikipedia.org/wiki/GNU_Screen&#34;&gt;screen&lt;/a&gt; script and launched it manuallyevery time I had to reboot my HTPC (which isn&amp;rsquo;t often). But there&amp;rsquo;s a prettycool feature of Runit &amp;ndash; &lt;a href=&#34;http://smarden.org/runit/faq.html#userservices&#34;&gt;user services&lt;/a&gt;. No more manually startingnzbget!:&lt;/p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/sh&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;exec 2&amp;gt;&amp;amp;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;exec /bin/nzbget --server&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With that run script and &lt;code&gt;/home/htpc/{sv,service}&lt;/code&gt; I can let Runit take careof starting and stopping it. All while not having to jump through a bunch ofhoops to start it as a specific user. This is something I&amp;rsquo;d love to use at work,but I&amp;rsquo;m stuck with RedHat and I&amp;rsquo;m not going to put another init system on topof an existing one (maybe).&lt;/p&gt;&lt;p&gt;Anyway, the point of this post was mainly to highlight Runit and Void Linux.They are a great combination for an appliance system like an HTPC. Such a systemdoesn&amp;rsquo;t need a lot of resources, but it is better to give the actual applicationthe majority of the resources. With Void and Runit your application getsalmost &lt;em&gt;all&lt;/em&gt; of the system resources. I&amp;rsquo;ll end this post with the statson my HTPC&amp;rsquo;s currently used resources:&lt;/p&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;% free -h                                                                                                                                                   [s:127 l:385]              total        used        free      shared  buff/cache   availableMem:           7.7G        475M        2.8G         57M        4.4G        7.1GSwap:            0B          0B          0B% ps_mem                                                                                                                                                 [s:1 l:392] Private  +   Shared  =  RAM usedProgram 92.0 KiB +  23.5 KiB = 115.5 KiBnanoklogd100.0 KiB +  26.0 KiB = 126.0 KiBsocklog124.0 KiB +  38.0 KiB = 162.0 KiBuuidd132.0 KiB +  71.5 KiB = 203.5 KiBkodi180.0 KiB +  38.5 KiB = 218.5 KiBacpid176.0 KiB +  73.0 KiB = 249.0 KiBrunsvdir (2)192.0 KiB + 132.0 KiB = 324.0 KiBsh (2)216.0 KiB + 169.0 KiB = 385.0 KiBautox (2)200.0 KiB + 236.0 KiB = 436.0 KiBxinit448.0 KiB + 166.0 KiB = 614.0 KiBsvlogd (5)448.0 KiB + 219.0 KiB = 667.0 KiBagetty (4)704.0 KiB +   4.0 KiB = 708.0 KiBrunit740.0 KiB + 272.0 KiB =   1.0 MiBlogin (2)932.0 KiB + 132.5 KiB =   1.0 MiBsudo  1.0 MiB +  90.5 KiB =   1.1 MiBudevd  1.4 MiB + 506.5 KiB =   1.9 MiBrunsv (19)  1.6 MiB + 395.0 KiB =   1.9 MiBwpa_supplicant  2.3 MiB + 109.5 KiB =   2.4 MiBmost  2.6 MiB + 461.5 KiB =   3.1 MiBmandoc  2.9 MiB + 437.5 KiB =   3.3 MiBnmbd  1.2 MiB +   2.7 MiB =   3.9 MiBsshd (5)  4.2 MiB +   4.3 MiB =   8.5 MiBsmbd (2)  7.6 MiB +   1.3 MiB =   8.9 MiBmosh-server (2) 12.2 MiB + 562.5 KiB =  12.8 MiBx11vnc 11.1 MiB +   2.4 MiB =  13.6 MiBzsh (6) 14.9 MiB + 811.0 KiB =  15.7 MiBnzbget 29.2 MiB +   1.8 MiB =  31.0 MiBXorg411.8 MiB +   5.2 MiB = 417.0 MiBkodi.bin---------------------------------                        531.1 MiB=================================% pstree                                                                                                                                                      [s:0 l:386]runit─┬─2*[mosh-server───zsh]      └─runsvdir─┬─runsv─┬─socklog                 │       └─svlogd                 ├─4*[runsv───agetty]                 ├─runsv───sshd─┬─sshd───sshd───zsh                 │              └─sshd───sshd───zsh───pstree                 ├─runsv───uuidd                 ├─runsv───login───zsh                 ├─runsv───smbd───smbd                 ├─runsv───nanoklogd                 ├─runsv─┬─svlogd                 │       └─wpa_supplicant                 ├─runsv─┬─mythlogin───autox───sh───xinit─┬─Xorg───{Xorg}                 │       │                                └─sh───kodi───kodi.bin─┬─{AESink}                 │       │                                                       ├─{ActiveAE}                 │       │                                                       ├─{AirPlayServer}                 │       │                                                       ├─{EventServer}                 │       │                                                       ├─{FDEventMonitor}                 │       │                                                       ├─23*[{LanguageInvoker}]                 │       │                                                       ├─{PeripBusUSBUdev}                 │       │                                                       ├─{TCPServer}                 │       │                                                       ├─17*[{kodi.bin}]                 │       │                                                       └─2*[{libmicrohttpd}]                 │       └─svlogd                 ├─runsv───login───zsh───man───most                 ├─runsv───nmbd                 ├─runsv───udevd                 ├─runsv───acpid                 ├─runsv─┬─svlogd                 │       └─x11vnc                 └─runsv───runsvdir───runsv─┬─nzbget───6*[{nzbget}]                                            └─svlogd&lt;/code&gt;&lt;/pre&gt;</description>
     </item>
   
     <item>
       <title>Goodbye Wordpress!</title>
       <link>https://jrfom.com/posts/2015/11/29/goodbye-wordpress/</link>
       <pubDate>Sun, 29 Nov 2015 17:15:00 -0500</pubDate>
       
       <guid>https://jrfom.com/posts/2015/11/29/goodbye-wordpress/</guid>
       <description>&lt;p&gt;For the last five years this site has been generated by &lt;a href=&#34;http://wordpress.org/&#34;&gt;Wordpress&lt;/a&gt;.The &lt;a href=&#34;http://jrfom.com/2010/03/06/welcome-to-the-new-room-full-of-mirrors/&#34;&gt;decision&lt;/a&gt; to move to Wordpress was based primarily on theammount of spam that was being posted through the comment system I had written.Wordpress provides some great tools for fighting comment spam. But commentson weblog posts are becoming more irrelvant by the day; or rather, no onedoes it anymore. So I don&amp;rsquo;t have need of that feature any longer.&lt;/p&gt;&lt;p&gt;But that&amp;rsquo;s not why I have dumped Wordpress. I have dumped Wordpress becauseit is one giant security hole:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&#34;http://arstechnica.com/security/2015/02/more-than-1-million-wordpress-websites-imperiled-by-critical-plugin-bug/&#34;&gt;http://arstechnica.com/security/2015/02/more-than-1-million-wordpress-websites-imperiled-by-critical-plugin-bug/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;http://arstechnica.com/security/2015/04/just-released-wordpress-0day-makes-it-easy-to-hijack-millions-of-websites/&#34;&gt;http://arstechnica.com/security/2015/04/just-released-wordpress-0day-makes-it-easy-to-hijack-millions-of-websites/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;http://arstechnica.com/security/2015/04/as-many-as-1-million-sites-imperiled-by-dangerous-bug-in-wordpress-plugin/&#34;&gt;http://arstechnica.com/security/2015/04/as-many-as-1-million-sites-imperiled-by-dangerous-bug-in-wordpress-plugin/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;http://arstechnica.com/security/2015/04/swarm-of-wordpress-plugins-susceptible-to-potentially-dangerous-exploits/&#34;&gt;http://arstechnica.com/security/2015/04/swarm-of-wordpress-plugins-susceptible-to-potentially-dangerous-exploits/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&#34;http://arstechnica.com/security/2015/05/actively-exploited-wordpress-bug-puts-millions-of-sites-at-risk/&#34;&gt;http://arstechnica.com/security/2015/05/actively-exploited-wordpress-bug-puts-millions-of-sites-at-risk/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I could keep linking stories of its vulnerabilities all day. Suffice it to say,it is foolish to continue using Wordpress.&lt;/p&gt;&lt;p&gt;Given that fact, I decided to forego a dynamically generated website altogether.This site is now completely static. This site is written in nothing more thanplain old HTML, CSS, and JavaScript. That used to come at a cost ofmaintainability. It was far easier to use a dynamic content generator for asite of any size if you wanted to be able to maintain it. Nowadays that isn&amp;rsquo;tthe case. There are many, &lt;em&gt;many&lt;/em&gt;, tools for generating static websites.I even &lt;a href=&#34;https://bitbucket.org/jsumners/njsbaker&#34;&gt;wrote one&lt;/a&gt; at one point (you probably shouldn&amp;rsquo;t use it).&lt;/p&gt;&lt;p&gt;The tool I settled on using is &lt;a href=&#34;http://metalsmith.io/&#34;&gt;Metalsmith&lt;/a&gt;. It&amp;rsquo;s a very simpletool with a lot of flexibility. I won&amp;rsquo;t go over it in detail here. You can&lt;a href=&#34;http://www.robinthrift.com/posts/metalsmith-part-1-setting-up-the-forge/&#34;&gt;read about&lt;/a&gt; in detail &lt;a href=&#34;http://www.okaythree.com/2015/03/building-a-blog-with-metalsmith/&#34;&gt;elsewhere&lt;/a&gt;. If you are curiousabout the code to generate this site, you can peruse the&lt;a href=&#34;https://github.com/jsumners/jrfom.com&#34;&gt;git repository&lt;/a&gt;. At the time of this writing the project is justenough to get going.&lt;/p&gt;&lt;p&gt;If you&amp;rsquo;re using Wordpress, and want to migrate off it, then I have written atool you might want to use &amp;ndash; &lt;a href=&#34;https://github.com/jsumners/wp-to-static&#34;&gt;wp-to-static&lt;/a&gt;. I had been wantingto do this migration since early 2015, but it took me a while to finishwriting that tool (mostly due to laziness). I&amp;rsquo;m a firm believer in the&lt;a href=&#34;https://httpstatuses.com/301&#34;&gt;301 code&lt;/a&gt;. As a result, all of my old content is still&lt;a href=&#34;http://jrfom.com/2015archive/&#34;&gt;available&lt;/a&gt;; even my old &lt;em&gt;old&lt;/em&gt; &lt;a href=&#34;http://jrfom.com/2010archive/&#34;&gt;content&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Anyway, I have been holding off writing new posts because I didn&amp;rsquo;t want toadd any more content to Wordpress. Now that I&amp;rsquo;ve moved on to this setupI will maybe write more frequently. My current goal, though, is to come up withsome sort of better template/design.&lt;/p&gt;&lt;p&gt;Finally, I may consider adding &lt;a href=&#34;https://disqus.com/&#34;&gt;Disqus&lt;/a&gt; comment system.But it&amp;rsquo;s unlikely. If you have something to say about a post, you can mention&lt;a href=&#34;https://twitter.com/jsumners79&#34;&gt;@jsumners79&lt;/a&gt; on Twitter or&lt;a href=&#34;https://plus.google.com/+JamesSumners&#34;&gt;+JamesSumners&lt;/a&gt; on Google+.&lt;/p&gt;</description>
     </item>
   
 </channel>
</rss>
