<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>William Vaughn</title>
    <link>http://willvaughn.org/</link>
    <description>Recent content on William Vaughn</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Tue, 17 Jun 2025 13:04:00 -0700</lastBuildDate><atom:link href="http://willvaughn.org/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Psalm 106</title>
      <link>http://willvaughn.org/articles/psalm-106/</link>
      <pubDate>Tue, 17 Jun 2025 13:04:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/psalm-106/</guid>
      <description>&lt;div class=&#34;verse&#34;&gt;
&lt;p&gt;&lt;strong&gt;Give Thanks to the Lord, for He Is Good&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
106 Praise the Lord!&lt;br /&gt;
Oh give thanks to the Lord, for he is good,&lt;br /&gt;
    for his steadfast love endures forever!&lt;br /&gt;
2 Who can utter the mighty deeds of the Lord,&lt;br /&gt;
    or declare all his praise?&lt;br /&gt;
3 Blessed are they who observe justice,&lt;br /&gt;
    who do righteousness at all times!&lt;br /&gt;
&lt;br /&gt;
4 Remember me, O Lord, when you show favor to your people;&lt;br /&gt;
    help me when you save them,[a]&lt;br /&gt;
5 that I may look upon the prosperity of your chosen ones,&lt;br /&gt;
    that I may rejoice in the gladness of your nation,&lt;br /&gt;
    that I may glory with your inheritance.&lt;br /&gt;
&lt;br /&gt;
6 Both we and our fathers have sinned;&lt;br /&gt;
    we have committed iniquity; we have done wickedness.&lt;br /&gt;
7 Our fathers, when they were in Egypt,&lt;br /&gt;
    did not consider your wondrous works;&lt;br /&gt;
they did not remember the abundance of your steadfast love,&lt;br /&gt;
    but rebelled by the sea, at the Red Sea.&lt;br /&gt;
8 Yet he saved them for his name&amp;rsquo;s sake,&lt;br /&gt;
    that he might make known his mighty power.&lt;br /&gt;
9 He rebuked the Red Sea, and it became dry,&lt;br /&gt;
    and he led them through the deep as through a desert.&lt;br /&gt;
10 So he saved them from the hand of the foe&lt;br /&gt;
    and redeemed them from the power of the enemy.&lt;br /&gt;
11 And the waters covered their adversaries;&lt;br /&gt;
    not one of them was left.&lt;br /&gt;
12 Then they believed his words;&lt;br /&gt;
    they sang his praise.&lt;br /&gt;
&lt;br /&gt;
13 But they soon forgot his works;&lt;br /&gt;
    they did not wait for his counsel.&lt;br /&gt;
14 But they had a wanton craving in the wilderness,&lt;br /&gt;
    and put God to the test in the desert;&lt;br /&gt;
15 he gave them what they asked,&lt;br /&gt;
    but sent a wasting disease among them.&lt;br /&gt;
&lt;br /&gt;
16 When men in the camp were jealous of Moses&lt;br /&gt;
    and Aaron, the holy one of the Lord,&lt;br /&gt;
17 the earth opened and swallowed up Dathan,&lt;br /&gt;
    and covered the company of Abiram.&lt;br /&gt;
18 Fire also broke out in their company;&lt;br /&gt;
    the flame burned up the wicked.&lt;br /&gt;
&lt;br /&gt;
19 They made a calf in Horeb&lt;br /&gt;
    and worshiped a metal image.&lt;br /&gt;
20 They exchanged the glory of God[b]&lt;br /&gt;
    for the image of an ox that eats grass.&lt;br /&gt;
21 They forgot God, their Savior,&lt;br /&gt;
    who had done great things in Egypt,&lt;br /&gt;
22 wondrous works in the land of Ham,&lt;br /&gt;
    and awesome deeds by the Red Sea.&lt;br /&gt;
23 Therefore he said he would destroy them—&lt;br /&gt;
    had not Moses, his chosen one,&lt;br /&gt;
stood in the breach before him,&lt;br /&gt;
    to turn away his wrath from destroying them.&lt;br /&gt;
&lt;br /&gt;
24 Then they despised the pleasant land,&lt;br /&gt;
    having no faith in his promise.&lt;br /&gt;
25 They murmured in their tents,&lt;br /&gt;
    and did not obey the voice of the Lord.&lt;br /&gt;
26 Therefore he raised his hand and swore to them&lt;br /&gt;
    that he would make them fall in the wilderness,&lt;br /&gt;
27 and would make their offspring fall among the nations,&lt;br /&gt;
    scattering them among the lands.&lt;br /&gt;
&lt;br /&gt;
28 Then they yoked themselves to the Baal of Peor,&lt;br /&gt;
    and ate sacrifices offered to the dead;&lt;br /&gt;
29 they provoked the Lord to anger with their deeds,&lt;br /&gt;
    and a plague broke out among them.&lt;br /&gt;
30 Then Phinehas stood up and intervened,&lt;br /&gt;
    and the plague was stayed.&lt;br /&gt;
31 And that was counted to him as righteousness&lt;br /&gt;
    from generation to generation forever.&lt;br /&gt;
&lt;br /&gt;
32 They angered him at the waters of Meribah,&lt;br /&gt;
    and it went ill with Moses on their account,&lt;br /&gt;
33 for they made his spirit bitter,[c]&lt;br /&gt;
    and he spoke rashly with his lips.&lt;br /&gt;
&lt;br /&gt;
34 They did not destroy the peoples,&lt;br /&gt;
    as the Lord commanded them,&lt;br /&gt;
35 but they mixed with the nations&lt;br /&gt;
    and learned to do as they did.&lt;br /&gt;
36 They served their idols,&lt;br /&gt;
    which became a snare to them.&lt;br /&gt;
37 They sacrificed their sons&lt;br /&gt;
    and their daughters to the demons;&lt;br /&gt;
38 they poured out innocent blood,&lt;br /&gt;
    the blood of their sons and daughters,&lt;br /&gt;
whom they sacrificed to the idols of Canaan,&lt;br /&gt;
    and the land was polluted with blood.&lt;br /&gt;
39 Thus they became unclean by their acts,&lt;br /&gt;
    and played the whore in their deeds.&lt;br /&gt;
&lt;br /&gt;
40 Then the anger of the Lord was kindled against his people,&lt;br /&gt;
    and he abhorred his heritage;&lt;br /&gt;
41 he gave them into the hand of the nations,&lt;br /&gt;
    so that those who hated them ruled over them.&lt;br /&gt;
42 Their enemies oppressed them,&lt;br /&gt;
    and they were brought into subjection under their power.&lt;br /&gt;
43 Many times he delivered them,&lt;br /&gt;
    but they were rebellious in their purposes&lt;br /&gt;
    and were brought low through their iniquity.&lt;br /&gt;
&lt;br /&gt;
44 Nevertheless, he looked upon their distress,&lt;br /&gt;
    when he heard their cry.&lt;br /&gt;
45 For their sake he remembered his covenant,&lt;br /&gt;
    and relented according to the abundance of his steadfast love.&lt;br /&gt;
46 He caused them to be pitied&lt;br /&gt;
    by all those who held them captive.&lt;br /&gt;
&lt;br /&gt;
47 Save us, O Lord our God,&lt;br /&gt;
    and gather us from among the nations,&lt;br /&gt;
that we may give thanks to your holy name&lt;br /&gt;
    and glory in your praise.&lt;br /&gt;
&lt;br /&gt;
48 Blessed be the Lord, the God of Israel,&lt;br /&gt;
    from everlasting to everlasting!&lt;br /&gt;
And let all the people say, “Amen!”&lt;br /&gt;
    Praise the Lord!&lt;br /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I put the whole poem in because I think it&amp;rsquo;s a good recap of a lot of the old testament stories for those that don&amp;rsquo;t know it. The story of the Israelites is one of repeated brokeness and sin. They were sinned against as slaves in Egypt to the point that all they knew was a life of sin. God rescued them, because of his purpose to reveal himself to all the world through them. They struggle to break their cycles of sin, and God is patient, caring, and forgiving even though they don&amp;rsquo;t deserve it. Many people, even those who have tried to read the bible, will dismiss it because they find a lot of genuinely terrible things happening, and it can be difficult to discern when the bible is being &lt;em&gt;descriptive&lt;/em&gt; vs &lt;em&gt;prescriptive&lt;/em&gt;. This psalm is a reminder that God&amp;rsquo;s will for us is good, that he is the great cure for the disease of sin that breaks the world around us.&lt;/p&gt;
&lt;p&gt;Verses 34-48 compelled me over the edge to post this. It occurred to me that one thing non-believers and atheists (I used to be one) don&amp;rsquo;t credit God for, is how his true followers created the values of the modern world they know. Non-believers will focus on the evils of religion that people have perpetrated in God&amp;rsquo;s name (which is undeniable, by the way). Christ would be the first to call out the hypocrisy, and we as followers of him have a duty to follow that example to build the world described in verses 1-5. However, if we forget or reject God&amp;rsquo;s love, and desire a world without it, it will will be given to us. That&amp;rsquo;s not the world we want, and it&amp;rsquo;s not a better world. Maybe that&amp;rsquo;s an explanation for what we see happening in our world now? These verses are a reminder that the world before God, and before Christ, was a place of unmitigated evil. Sacrificing and abandoning children was normalized or even required. Worship of pagan gods was often a corporate sexual worship (orgy) that created pain and brokeness in communities through a cycle of sex slavery, sex obsession, and sex abuse. These things should anger you, and they anger God. Thank God for that! Thank God and praise him that his love is abundant and steadfast to save us from ourselves, if we will let him. Will you let him?&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Psalm 52</title>
      <link>http://willvaughn.org/articles/psalm-52/</link>
      <pubDate>Mon, 02 Jun 2025 11:43:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/psalm-52/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m still on the plan, but it has been so difficult to find time for all the reading and especially the blog writing in the midst of everything I have going on. Not mere business, but significant trials of health in our family. I find David&amp;rsquo;s laments in the Psalms heartening and his calls to trust fully in the Lord absolutely necessary. In the plan we&amp;rsquo;re in 1 Samuel, while also bouncing into the Psalms of David that match up to the story. This Psalm 52, is not a lament, it is a rebuke on Saul and Doeg the Edomite, while also being David&amp;rsquo;s declaration to wait on the Lord rather than depending on himself. It saddens me because it reminds me that there are so many people in this world who trust in themselves to their own destruction. I think of powerful people who through self-deception or malice love lies more than truth. I think of everyday people who trust lies the world tells them, and so never seek God as their protector and truth. When people trust in themselves, or in their success, their riches, their abilities, or anything other than God, what they have actually pursued is their own destruction.&lt;/p&gt;
&lt;div class=&#34;verse&#34;&gt;
&lt;p&gt;&lt;strong&gt;The Steadfast Love of God Endures&lt;/strong&gt;&lt;br /&gt;
To the choirmaster. A Maskil of David, when Doeg, the Edomite, came and told Saul, “David has come to the house of Ahimelech.”&lt;br /&gt;
&lt;br /&gt;
1 Why do you boast of evil, O mighty man?&lt;br /&gt;
   The steadfast love of God endures all the day.&lt;br /&gt;
2 Your tongue plots destruction,&lt;br /&gt;
   like a sharp razor, you worker of deceit.&lt;br /&gt;
3 You love evil more than good,&lt;br /&gt;
   and lying more than speaking what is right. Selah&lt;br /&gt;
4 You love all words that devour,&lt;br /&gt;
   O deceitful tongue.&lt;br /&gt;
5 But God will break you down forever;&lt;br /&gt;
   he will snatch and tear you from your tent;&lt;br /&gt;
   he will uproot you from the land of the living. Selah&lt;br /&gt;
6 The righteous shall see and fear,&lt;br /&gt;
   and shall laugh at him, saying,&lt;br /&gt;
7 “See the man who would not make&lt;br /&gt;
   God his refuge, but trusted in the abundance of his riches&lt;br /&gt;
   and sought refuge in his own destruction!”&lt;br /&gt;
8 But I am like a green olive tree in the house of God.&lt;br /&gt;
   I trust in the steadfast love of God forever and ever.&lt;br /&gt;
9 I will thank you forever, because you have done it.&lt;br /&gt;
   I will wait for your name, for it is good, in the preseence of the godly.&lt;br /&gt;
&lt;br /&gt;
The Holy Bible: English Standard Version (Wheaton, IL: Crossway Bibles, 2016), Ps 52:title–9.&lt;br /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I am praying for God to grant me His presence and to keep me close. I want to trust fully in Him even when it is difficult. I lack the diligence and discipline to do it, God must transform my habits, my life, and my heart to draw me in. Amen!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Leviticus 16:20-22, 17:10-16</title>
      <link>http://willvaughn.org/articles/leviticus-16-17/</link>
      <pubDate>Sun, 09 Mar 2025 09:53:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/leviticus-16-17/</guid>
      <description>&lt;div class=&#34;verse&#34;&gt;
&lt;p&gt;20 &amp;ldquo;And when he has made an end of atoning for the Holy Place and the tent of meeting and the altar, he shall present the live goat. 21 And Aaron shall lay both his hands on the head of the live goat, and confess over it all the iniquities of the people of Israel, and all their transgressions, all their sins. And he shall put them on the head of the goat and send it away into the wilderness by the hand of a man who is in readiness. 22 The goat shall bear all their iniquities on itself to a remote area, and he shall let the goat go free in the wilderness.&lt;br /&gt;
&lt;br /&gt;
ESV Leviticus 16:20-22&lt;br /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;verse&#34;&gt;
&lt;p&gt;10 &amp;ldquo;If any one of the house of Israel or of the strangers who sojourn among them eats any blood, I will set my face against that person who eats blood and will cut him off from among his people. 11 For the life of the flesh is in the blood, and I have given it for you on the altar to make atonement for your souls, for it is the blood that makes atonement by the life. 12 Therefore I have said to the&lt;br /&gt;
people of Israel, No person among you shall eat blood, neither shall any stranger who sojourns among you eat blood. 13 &amp;ldquo;Any one also of the people of Israel, or of the strangers who sojourn among them, who takes in hunting any beast or bird that may be eaten shall pour out its blood and cover it with earth. 14 For the life of every creature is its blood: its blood is its life. Therefore I have said to the people of Israel, You shall not eat the blood of any creature, for the life of every creature is its blood. Whoever eats it shall be cut off. 15 And every person who eats what dies of itself or what is torn by beasts, whether he is a native or a sojourner, shall wash his clothes and bathe himself in water and be unclean until the evening; then he shall be clean. 16 But if he does not wash them or bathe his flesh, he shall bear his iniquity.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ESV Leviticus 17:10-16&lt;br /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Since the rebellion in Genesis 3, God has established that the necessary payment for sin, is death. Here in Leviticus, God is setting up a system of sacrifice and atonement for His people by which they must face the graphic consequence of their sin, but can also be forgiven of it. The exchange of blood, as the source of life, is the cost that God accepts for forgiveness. This sacrificial system established in Levitical law is pointing us to our need for an ultimate and perfect sacrifice that could cover all the sin of the entire world.&lt;/p&gt;
&lt;p&gt;Though it is not in these particular verses, there is another goat that is bled to pay the debt of the Israelites. The one in these verses is the scapegoat. It carries the burden of sins for all the people, and it takes them away. It is cast out from the safety and protection of the camp and into the wilderness to die. Jesus was similarly cast out from His people when he was taken outside of Jerusalem to die. He carried the burden of the the world&amp;rsquo;s sin, and paid for it with his blood on a cross. His promise was to bring those who look to Him into a right relationship with God through His perfect sacrifice. Thank you, Lord! May the news of your goodness spread forever and call our hearts to rest in you!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Genesis</title>
      <link>http://willvaughn.org/articles/genesis/</link>
      <pubDate>Thu, 13 Feb 2025 12:38:00 -0800</pubDate>
      
      <guid>http://willvaughn.org/articles/genesis/</guid>
      <description>&lt;p&gt;Let&amp;rsquo;s be real, there are a lot of places in the book of Genesis where you&amp;rsquo;re going to go &amp;ldquo;Ewww!&amp;rdquo;. Here&amp;rsquo;s a sample:&lt;/p&gt;
&lt;p&gt;Cain murders Abel over simple jealousy. Ugh!&lt;/p&gt;
&lt;p&gt;Something fairly undefined happens between Noah and one of his sons. It&amp;rsquo;s not clear what, but it has to do with one of them disrespecting him when they found him sleeping naked. Ewww?&lt;/p&gt;
&lt;p&gt;When Lot is trying to prevent the men of Sodom from raping his house guests, he tries to distract them by offering to let them rape his daughters instead. They&amp;rsquo;re undeterred. Ugly on multiple levels!&lt;/p&gt;
&lt;p&gt;After Sodom and Gomorrah have been destroyed, Lot&amp;rsquo;s daughters get him drunk and get themselves pregnant by him. Ewww!&lt;/p&gt;
&lt;p&gt;Judah finds a wife for his son Er, her name is Tamar. Er is apparently evil, and God lets him die. Then Judah tells his other son Onan, &amp;ldquo;Okay, you go into her and have kids with her.&amp;rdquo; But Onan, uses the pull-out method to make sure he doesn&amp;rsquo;t get her pregnant. So God lets him die too. Tamar, a single, twice-widowed, childless, woman with no husband (basically a death sentence) is told to go back to her father&amp;rsquo;s house and wait until Judah&amp;rsquo;s youngest son, Shelah, is old enough to marry. When Shelah is old enough to marry, Tamar veils herself to get a look at him, and she&amp;rsquo;s wondering why she hasn&amp;rsquo;t been given to him in marriage yet. At that moment, Judah mistakes her for a prostitute and she goes along with it and becomes pregnant with twins! When it comes out that she&amp;rsquo;s been scandalous, she provides some proof of the prostitution incident and Judah realizes he was the one who messed up, and takes her for his own wife. Yeesh!&lt;/p&gt;
&lt;p&gt;God makes a promise to be faithful to the children of Abraham and to bless the whole world through his descendants. All of his descendants though, they&amp;rsquo;re just normal people who do what normal people do. They mess up, make mistakes, do terrible things. But God, keeps his word and works it out the way he said he would anyway. That&amp;rsquo;s how Genesis goes for 40 chapters, until it ends with what I think is one of the most incredible stories in the Bible, the story of Joseph. This is where God works everything out for the good. Joseph&amp;rsquo;s brother&amp;rsquo;s get jealous of him (sort of like Cain did to Abel), they stop just short of killing him by selling him into slavery. They do evil to their brother, and they lie about it. God uses their evil to put Joseph second in command of Egypt. He gifts Joseph with insights and wisdom to prepare for a major famine, and in doing so he&amp;rsquo;s able to save the lives of thousands of people in and around Egypt, including the lives of his brothers. He reconciles with his brothers, and forgives them. Joseph fully yields to the goodness and provision of God. In the end of Genesis we find a picture of God&amp;rsquo;s grace and mercy. He brings all of the Israelites to Egypt to live and multiply for several hundred years until they&amp;rsquo;re ready to live out the next phase of his plan for them.&lt;/p&gt;
&lt;p&gt;If you were to look at what the people say and do in Genesis as if it were the example to follow, you&amp;rsquo;d be right to question why it&amp;rsquo;s productive to believe in any of it. When I read this book as a non-believer, all it did was give me fuel to question even more why anyone would believe in this God. But when you instead focus on what God does and says throughout this story, you begin to see His character separately from the actions of people. If we&amp;rsquo;re to have a relationship with God as his children, we need to seek who He is rather than looking to the world for who they say He is. The world will show us hostility, immorality, hypocrisy, and violence and try to tell us that&amp;rsquo;s who God is. God shows us something else entirely.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Job 38:31-33; Job 39:9</title>
      <link>http://willvaughn.org/articles/job-38-39/</link>
      <pubDate>Thu, 30 Jan 2025 10:23:00 -0800</pubDate>
      
      <guid>http://willvaughn.org/articles/job-38-39/</guid>
      <description>&lt;p&gt;Finally, God speaks. Thirty-eight chapters of Job&amp;rsquo;s misery and bad advice from his friends. God sure is patient. First order of business from God, is to establish who He is. Chapters 38 and 39 are really just God expounding on His glory and reminding Job and his friends who they are in relation to Him. He is the God that binds everything together, and sets all things in their order. One thing I find remarkable about these chapters is that they&amp;rsquo;ve stood the test of like 3000 years of discovery. All of the things God lists in these chapters that are his doing, are still things that with all our science and discovery, we still don&amp;rsquo;t fully understand. We have better understandings of them perhaps, and in some cases we&amp;rsquo;ve actually validated some of what God says in this chapter. But, mostly these were deep mysteries then, and they remain deep mysteries now.&lt;/p&gt;
&lt;div class=&#34;verse&#34;&gt;
&lt;p&gt;31 &amp;ldquo;Can you bind the chains of the Pleiades&lt;br /&gt;
     or loose the cords of Orion?&lt;br /&gt;
32 Can you lead forth the Mazzaroth in their season,&lt;br /&gt;
     or can you guide the Bear with its children?&lt;br /&gt;
33 Do you know the ordinances of the heavens?&lt;br /&gt;
     Can you establish their rule on the earth?&lt;br /&gt;
&lt;br /&gt;
ESV Job 38:31-33&lt;br /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Whoa. &amp;ldquo;Hey you, little human, did you set all this up? Did you create all these constellations and this whole universe, and work out exactly how it would all fit together and establish order from where you look upon them on earth?&amp;rdquo; The &amp;ldquo;Mazzaroth&amp;rdquo; is a Hebrew word, but from context it must be a constellation. Most Northern Hemisphere dwellers know the &lt;a href=&#34;https://earthsky.org/favorite-star-patterns/pleiades-star-cluster-enjoys-worldwide-renown/&#34;&gt;Pleiades&lt;/a&gt;, &lt;a href=&#34;https://earthsky.org/tonight/orion-the-hunter-is-easy-to-spot/&#34;&gt;Orion&lt;/a&gt;, and &lt;a href=&#34;https://earthsky.org/constellations/ursa-major-great-bear-big-dipper/&#34;&gt;The Bear (Ursa Major)&lt;/a&gt;. I find it fascinating how human civilization has used the night sky for orientation, time keeping, navigation, myths, stories, and so much more. Here is God saying He, His Son, and His spirit worked out all that before time even began. God is big! I don&amp;rsquo;t want a God who is any less marvelous and mysterious. If we could understand the ways of God, He wouldn&amp;rsquo;t be worth worshipping. But, He is.&lt;/p&gt;
&lt;div class=&#34;verse&#34;&gt;
&lt;p&gt;&amp;ldquo;Is the wild ox willing to serve you?&lt;br /&gt;
   Will he spend the night at your manger?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ESV Job 39:9&lt;br /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;God continues in chapter 39, but now he&amp;rsquo;s covering the greatness of his command of all living creatures. He&amp;rsquo;s talking about knowing when and how the mountain goats give birth, and some stuff about sustaining wild donkeys in the salt lands. Then he puts in this little bit about how a wild ox would serve Him and spend the night by his manger. Do you know anyone born in a manger amongst barn animals? Yeah, maybe just maybe, in this book provably written thousands of years before it happened, God is giving a little hint at who He is, and what was to come. That Jesus, the living God would become human, be born in a manger to live a life we could never live, sacrificing himself for us so that we might have life and have it abundantly.&lt;/p&gt;
&lt;p&gt;I really liked reading Job. This was my first time through it. Can&amp;rsquo;t wait to come back around to it next year! Perhaps in the time of the Pleiades.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Job 21:7; Job 22:17; Job 23:12-14</title>
      <link>http://willvaughn.org/articles/job-21-7/</link>
      <pubDate>Tue, 21 Jan 2025 22:36:00 -0800</pubDate>
      
      <guid>http://willvaughn.org/articles/job-21-7/</guid>
      <description>&lt;div class=&#34;verse&#34;&gt;
&lt;p&gt;Why do the wicked live, reach old age, and grow mighty in power?&lt;br /&gt;
&lt;br /&gt;
ESV Job 21:7&lt;br /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This is Job speaking in his reply to the bad advice his friends have been giving him. Basically, they say Job suffers because he sinned and isn&amp;rsquo;t right with God.&lt;/p&gt;
&lt;div class=&#34;verse&#34;&gt;
&lt;p&gt;17 They said to God, ‘Depart from us,’&lt;br /&gt;
    and ‘What can the Almighty do to us?’&lt;br /&gt;
18 Yet he filled their houses with good things—&lt;br /&gt;
    but the counsel of the wicked is far from me.&lt;br /&gt;
&lt;br /&gt;
ESV Job 22:17&lt;br /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Job knows God is just. He doesn&amp;rsquo;t fully understand why things are going so bad for him, but he knows and trusts that God is just. Ultimately, no one gets away with anything, but sometimes we want God to be immediate in carrying out justice, or to relent in our sufferings. We wonder, &amp;ldquo;Why haven&amp;rsquo;t you punished those that hate you, deny you, and work against you Lord? Why do people get away with being evil? Not only are they getting away with it, they&amp;rsquo;re thriving!&amp;rdquo; Job&amp;rsquo;s friends seem to think the world works like this: the wicked suffer, and the godly prosper. We see whole sects of religion subscribing to that theology, and preying on folks who want to believe it. The reality is that God allows us to be lost in our own evil, to depart from Him, and to have what we want; our world without Him. That can even go so well that we convince ourselves we don&amp;rsquo;t need God, and we&amp;rsquo;re in some sense our own God, in control of our own fate, our own standard for morality. It&amp;rsquo;s not what He wants for us, but He gives us the freedom.&lt;/p&gt;
&lt;p&gt;Do we really want God to be immediate in His justice? I don&amp;rsquo;t know about you, but that wouldn&amp;rsquo;t end well for me. No, we rejoice that God doesn&amp;rsquo;t do what is &amp;ldquo;fair&amp;rdquo;, instead he gives us unimaginable mercy by saving us from what we deserve. He gives us his amazing grace, far more than we deserve, if we will turn to Him.&lt;/p&gt;
&lt;div class=&#34;verse&#34;&gt;
&lt;p&gt;12 I have not departed from the commandment of his lips;&lt;br /&gt;
     I have treasured the words of his mouth more than my portion of food.&lt;br /&gt;
13 But he is unchangeable, and who can turn him back?&lt;br /&gt;
     What he desires, that he does.&lt;br /&gt;
14 For he will complete what he appoints for me,&lt;br /&gt;
     and many such things are in his mind.&lt;br /&gt;
&lt;br /&gt;
ESV Job 23:12–14.&lt;br /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;God does as he desires, he completes what he appoints. All manner of bad stuff is happening to Job, but the state of his heart is aligned directly toward God. God is always after our heart, and circumstances don&amp;rsquo;t always reflect the state of our heart.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Genesis 11:4-6</title>
      <link>http://willvaughn.org/articles/genesis-11-4-6/</link>
      <pubDate>Tue, 14 Jan 2025 10:44:00 -0800</pubDate>
      
      <guid>http://willvaughn.org/articles/genesis-11-4-6/</guid>
      <description>&lt;div class=&#34;verse&#34;&gt;
&lt;p&gt;Then they said, &amp;ldquo;Come, let us build ourselves a city and a tower with its top in the heavens, and let us make a name for ourselves, lest we be dispersed over the face of the whole earth.&amp;rdquo; And the LORD came down to see the city and the tower, which the children of man had built. And the LORD said, &amp;ldquo;Behold, they are one people, and they have all one language, and this is only the beginning of what they will do. And nothing that they propose to do will now be impossible for them.&lt;br /&gt;
&lt;br /&gt;
Genesis 11:4-6&lt;br /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Most people know this story as the &amp;ldquo;Tower of Babel&amp;rdquo;. God commanded the people to fill the earth several times (Gen 1:22,28, 9:1,7), and here they are puffed up on themselves, their own greatness, achievements, and self-sufficiency. They are planning to build a tower to reach heaven so they don&amp;rsquo;t have to be &amp;ldquo;dispersed over the face of the whole earth&amp;rdquo;. What I saw in the author&amp;rsquo;s character and God&amp;rsquo;s character here is humor. It&amp;rsquo;s hilarious, to me, that God has to come &amp;ldquo;down&amp;rdquo; in order to see their tower. Wasn&amp;rsquo;t this thing supposed to reach heaven? Even though it falls way short of the glory of God and the heavens, God still has the wisdom to look into their hearts for the true motivations for their pursuit. He calls it &amp;ldquo;only the beginning of what they will do&amp;rdquo;. I think what they &amp;ldquo;propose&amp;rdquo; to do is to replace their own need for God, and God is admitting that this proposal won&amp;rsquo;t be &amp;ldquo;impossible&amp;rdquo; for them to achieve. They&amp;rsquo;ll achieve it. We see that in our world now don&amp;rsquo;t we? Many people and cultures confident in their technology and own abilities. Powerful people puffed up on their own greatness, making themselves out to be more than they are.&lt;/p&gt;
&lt;p&gt;Well, in this case God was working his plan to reveal himself to the world through Abram and the Jews, so he needed the people to disperse like he told them to do. Despite them trying again to mess up the plan, he confuses them with a language change, they tribe up and disperse over the earth exactly as planned.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Can I read the whole Bible this year?</title>
      <link>http://willvaughn.org/articles/can-i-read-the-whole-bible-this-year/</link>
      <pubDate>Mon, 13 Jan 2025 20:18:00 -0800</pubDate>
      
      <guid>http://willvaughn.org/articles/can-i-read-the-whole-bible-this-year/</guid>
      <description>&lt;p&gt;It still blows my mind that I am a born-again Christian. If you knew me before, I&amp;rsquo;m sure you relate with that. If you think you&amp;rsquo;re weirded out by this change, imagine how I must feel! Truthfully, it is something shocking to think that even though I denounced and dismissed God (and anyone who believes in God) for so many years, He chose me anyway. I don&amp;rsquo;t fully comprehend all the things He weaved together to bring me to a moment of true repentance, where I finally comprehended the significance of words I had heard a thousand times, came to an end of insisting I was in control, and chose to believe something I&amp;rsquo;d spent most of my life denying. But, somehow He did. In an instant I knew in my heart that Jesus Christ had lived, said impossible things, did impossible things, willfully sacrificed Himself to erase a debt I owed, and then rose from the dead to prove that the payment was accepted. Crazy story right? When people ask, &amp;ldquo;Has anyone shared the Gospel with you?&amp;rdquo; this is it. The good news of a gift freely given and an opportunity to choose whether to dismiss it, or to accept it. This time I turned away from myself, toward a God who loves me, and I accepted. Doing that broke me. I started to sob uncontrollably. That word &amp;ldquo;uncontrollably&amp;rdquo; is for real, and it means I could not stop. It was kind of terrifying. I didn&amp;rsquo;t understand what was happening, but I look back now and understand it as a reaction to having the lies I&amp;rsquo;d centered my life around suddenly and drastically eroded. That moment everything changed. Every moment since has been different. In the moment that broke me, I admitted something that let Jesus in, and by letting him in He began the long work of changing me and building me back up. I admitted my actual helplessness. I admitted my own darkness. I admitted that there was a deep need for forgiveness in my life. That without forgiveness my life was lost, and that His forgiveness wasn&amp;rsquo;t something I could earn. It was something I had to accept.&lt;/p&gt;
&lt;p&gt;Maybe you&amp;rsquo;re like me, you don&amp;rsquo;t want it. Maybe you&amp;rsquo;re like me, someday you will. I don&amp;rsquo;t know. But, that born-again moment for me was the beginning of having the word of God opened up. I had read parts of The Bible before, but just to poke holes in it. Now I wanted to read it, and when I did it met me where I was at and started to make sense.&lt;/p&gt;
&lt;div class=&#34;verse&#34;&gt;
&lt;p&gt;The person without the Spirit does not accept the things that come from the Spirit of God but considers them foolishness, and cannot understand them because they are discerned only through the Spirit.&lt;br /&gt;
&lt;br /&gt;
1 Corinthians 2:14&lt;br /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Since then, I&amp;rsquo;ve read a lot of The Bible. But this year, I am following a chronological plan of God&amp;rsquo;s story. I&amp;rsquo;m not going to post a lengthy post like this everyday, don&amp;rsquo;t worry. But, when a passage catches me, I will post it with a brief explanation of what it reveals to me about the character of God. If you&amp;rsquo;re here for it, my hope is that together we&amp;rsquo;ll understand God more fully &amp;ndash; His purposes, His ways, His Mercy, and His love &amp;ndash; by seeking what He has to say about these things Himself.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Emacs shell-command</title>
      <link>http://willvaughn.org/articles/emacs-shell-command/</link>
      <pubDate>Thu, 07 Jul 2022 00:07:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/emacs-shell-command/</guid>
      <description>&lt;p&gt;When I used to use vim (or evil), I was able to use the &lt;code&gt;:read&lt;/code&gt; command to execute any random shell command and plop its output into my current buffer. My main use case was in using base64 to encode secret values into Kubernetes Secret YAML manifests. It went something like this:&lt;/p&gt;
&lt;p&gt;Go to the place in the buffer that I want to input a secret value.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;:read ! echo -n &amp;#39;Sup3rS3cr3t&amp;#39; | base64
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And that would place &lt;code&gt;U3VwM3JTM2NyM3Q=&lt;/code&gt; at the cursor, writing the base64 encoded value that was output from my shell command, executed from within vim.&lt;/p&gt;
&lt;p&gt;Recently, I learned how to do this in emacs. It is &lt;code&gt;M-!&lt;/code&gt;, or=shell-command=, to type in a command. And it is &lt;code&gt;M-|&lt;/code&gt;, or &lt;code&gt;shell-command-on-region&lt;/code&gt;, to run the shell command on the content of region (as STDIN).&lt;/p&gt;
&lt;p&gt;You can use the &lt;code&gt;C-u&lt;/code&gt; prefix to output the text resulting from the command to the buffer you run the command from.&lt;/p&gt;
&lt;p&gt;Example, decoding a value.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;C-u M-!&lt;/code&gt; enter &lt;code&gt;echo &#39;Sup3rS3cr3T&#39; | base64&lt;/code&gt; the output is, &lt;code&gt;U3VwM3JTM2NyM3Q=&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now if you highlight that region, you can run &lt;code&gt;C-u M-|&lt;/code&gt; input &lt;code&gt;cat | base64 -d&lt;/code&gt; and it&amp;rsquo;s replaced with &lt;code&gt;Sup3rS3cr3t&lt;/code&gt; again.&lt;/p&gt;
&lt;p&gt;Thanks for reading, hope you enjoy this one neat trick you might not be using in emacs. All the best!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>VP of Emacs: The Job</title>
      <link>http://willvaughn.org/articles/vp-of-emacs-the-job/</link>
      <pubDate>Sun, 15 May 2022 10:01:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/vp-of-emacs-the-job/</guid>
      <description>&lt;p&gt;&lt;em&gt;VP of Emacs&lt;/em&gt; is a blog series about using Emacs as an essential tool in my job as the VP of Software Engineering at Carbon Lighthouse. I&amp;rsquo;m a software engineer trying to cut it in a job that has required me to be more organized, communicative, strategic, and personal than ever. Emacs helps me get more done and keep it all connected. It has become the application I use every day to unify note-taking, emails, task management, writing, programming, and more.&lt;/p&gt;
&lt;p&gt;This edition is a step back from Emacs and the details of my configuration. I wanted to talk about what my job is and how I approach it. I believe it is important to know what I&amp;rsquo;m trying to achieve and why, before a tool, even a tool as versatile as Emacs, can be used to its full potential.&lt;/p&gt;
&lt;h2 id=&#34;people-process-system-strategy&#34;&gt;People, Process, System, Strategy&lt;/h2&gt;
&lt;p&gt;A technical advisor of mine shared these four aspects of the VP of Engineering role with me, &lt;em&gt;People, Process, System, and Strategy&lt;/em&gt;. When I heard them laid out like this, it resonated strongly with me. In a startup environment, the work of the VP role is often oscillating between developer, architect, product manager, coach, counselor, strategist, and diplomat. This should be expected, because the small team needs its leader to cover their gaps and be the glue that keeps things running smoothly. It is exhausting, though. At any given time, it is going to feel like one or more of these aspects is on fire. Even though they are all essential and important to the organization&amp;rsquo;s future success, they can&amp;rsquo;t all be equally important at any given time. I strive to be honest and forthcoming, both up and down the chain, about why I&amp;rsquo;m intentionally letting one aspect slip in order to focus on the others.&lt;/p&gt;
&lt;h3 id=&#34;people&#34;&gt;People&lt;/h3&gt;
&lt;p&gt;Supporting, hiring, and growing the skills of people in a software organization is essential for high performance. As a leader, I support people and I direct culture. My job is to provide an environment in which leadership, cooperation, accountability, and learning flourish. The behaviors that lead to better software for customers, and a lower cost of change, need to be the default behaviors of the organization. If doing the right thing can be easily resisted, it will be resisted. It&amp;rsquo;s my job to define what the right behaviors are.&lt;/p&gt;
&lt;h3 id=&#34;process&#34;&gt;Process&lt;/h3&gt;
&lt;p&gt;In every software company, there is a flow of work from &lt;em&gt;idea&lt;/em&gt; to &lt;em&gt;delivery&lt;/em&gt;. The production pipeline for code and the mechanisms of daily operations, are what I call &amp;ldquo;process&amp;rdquo;. Building a production pipeline can be as complex or more complex than the technological system and architecture it delivers. The organization&amp;rsquo;s lessons need to be constantly fed back into its process. Making sure the flow of critical information is present between the executive level, and every individual software engineer. When the executive level makes a shift that is out of step with reality at the engineering level, it is process which must amplify a feedback signal. Similarly, it is process which must ensure that what the engineers are doing is continually adjusting toward the strategic needs of the business and its customers.&lt;/p&gt;
&lt;h3 id=&#34;system&#34;&gt;System&lt;/h3&gt;
&lt;p&gt;The system is architecture, frameworks, tools, automation, infrastructure, and monitoring that must all work, and work well, in order for the team to build something customers continue to use. A technical leader needs to do more than understand the system. They have to guide and inspire change in it that leads to meaningful improvements in stability, malleability, velocity, and impact. Occasionally I do code-level spikes to understand, question, or measure what is good and bad about what we&amp;rsquo;ve already built or to discover new paths forward. People trust leaders who have done their job, or could do their job. If I lose touch with the work, I lose credibility too. There is a fine line here though, to not step over and do things that should be carried to completion by the team.&lt;/p&gt;
&lt;h3 id=&#34;strategy&#34;&gt;Strategy&lt;/h3&gt;
&lt;p&gt;It takes a lot to figure out the above three items, but it&amp;rsquo;s not enough. In this role, I&amp;rsquo;m the person that must be looking ahead to where the organization needs to go. Is there a business change coming soon that will require drastic changes? What are the next important improvements to make, and how do we sequence our growth to be where we want to be in 2 years time. What&amp;rsquo;s truly important? How do you communicate it and educate every person in the organization so they know it, feel it, and can act on it with intent?&lt;/p&gt;
&lt;h2 id=&#34;managerial-economics&#34;&gt;Managerial Economics&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;I can&amp;rsquo;t go do all the things I want done, I have to bring others into my reasoning and empower them to carry it out in their own way.&lt;/li&gt;
&lt;li&gt;Everything I do, that someone else could have done, was something I overpaid for while also robbing the team of a learning and growth opportunity. Double loss.&lt;/li&gt;
&lt;li&gt;80% of the work is done by 20% of the team. This means high performers, not low performers, should receive the majority of my focus, coaching, and guidance.&lt;/li&gt;
&lt;li&gt;Efficiency is accomplishing higher output with fewer resources. Productivity is doing more valuable work in the same unit of time. Delegation to the edges of the organization is what drives every member of the organization to focus on valuable work, while also increasing their capacity.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;hiring-and-recruitment&#34;&gt;Hiring &amp;amp; Recruitment&lt;/h2&gt;
&lt;p&gt;Hiring well is the most important responsibility of any manager. No hire is ever perfect, but a bad hire can be truly catastrophic to culture, communication, and productivity. I could write an entire blog on this subject, but here are my brief guiding principles on the subject.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Don&amp;rsquo;t hire, delegate more.&lt;/li&gt;
&lt;li&gt;Okay, you&amp;rsquo;ve decided to hire. Define the role, as well as the skills and behaviors that are necessary to perform in the role exceptionally.&lt;/li&gt;
&lt;li&gt;Build your hiring and interview process around finding reasons to pass on candidates, not reasons to hire them.&lt;/li&gt;
&lt;li&gt;Design your interview to investigate past behaviors and simulate the work of the role. There is no better predictor of future performance, than past performance.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;how-emacs-helps&#34;&gt;How Emacs Helps&lt;/h2&gt;
&lt;p&gt;Emacs is my tool for thought and data gathering. It forms the connections between my ideas and lets me recall them when I need them. My org mode index/inbox file is where every task I need to keep on top of lands by default. Org-agenda reminds me of things I deferred and helps me prioritize. Working in a single app affords me the advantage of doing less context switching and having higher integration between my notes, tasks, and email. I enjoy the freedom of being able to evolve my system of work, limited only by what I can configure or write in elisp. Most importantly, Emacs makes the work more fun because I enjoy using it.&lt;/p&gt;
&lt;h2 id=&#34;more-in-this-series&#34;&gt;More in this series&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;VP of Emacs&lt;/em&gt; series&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://willvaughn.org/articles/vp-of-emacs-a-personal-wiki-in-plain-text/&#34;&gt;VP of Emacs: A Personal Wiki in Plain Text&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://willvaughn.org/articles/vp-of-emacs-meeting-notes/&#34;&gt;VP of Emacs: Meeting Notes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks for reading. Please get in touch if you want to talk about engineering and leadership in your role, I&amp;rsquo;m happy to lend my perspective and learn from yours.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>VP of Emacs: Meeting Notes</title>
      <link>http://willvaughn.org/articles/vp-of-emacs-meeting-notes/</link>
      <pubDate>Sun, 13 Mar 2022 11:18:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/vp-of-emacs-meeting-notes/</guid>
      <description>&lt;p&gt;&lt;em&gt;VP of Emacs&lt;/em&gt; is a blog series about using Emacs as an essential tool in my job as the VP of Software Engineering at Carbon Lighthouse. I&amp;rsquo;m a software engineer trying to cut it in a job that has required me to be more organized, communicative, strategic, and personal than ever. Emacs helps me get more done and keep it all connected. It has become the application I use every day to unify note-taking, emails, task management, writing, programming, and more.&lt;/p&gt;
&lt;p&gt;Watch the &lt;a href=&#34;https://youtu.be/VKkWL%5F0YpTI&#34;&gt;YouTube video&lt;/a&gt; that accompanies this blog.&lt;/p&gt;
&lt;h2 id=&#34;meeting-notes-with-org-roam-dailies&#34;&gt;Meeting notes with Org-roam dailies&lt;/h2&gt;
&lt;p&gt;I don&amp;rsquo;t often take exhaustive meeting notes. Many meetings, especially in the post-pandemic world, have shared online notes taken in something like Google Docs anyway. What I find useful in my personal notes is to capture who the meeting attendees were, any links to resources relevant to the meeting, a summary of some main talking points, and any action required items. The people I have meetings with will have their own page in my Org-roam system. Many of the projects, milestones, and subjects that my meetings are about also have their own roam notes page. The linking and back-linking features give me a way to connect my meeting notes with the people I talked to and the subjects we talked about. Taking these meeting notes in &lt;a href=&#34;https://www.orgroam.com/manual.html#Org%5F002droam-Dailies&#34;&gt;Org-roam dailies&lt;/a&gt; files further connects those things to &lt;em&gt;when&lt;/em&gt; the discussion occurred.&lt;/p&gt;
&lt;p&gt;Org-roam dailies are a daily journaling feature in Org-roam. They&amp;rsquo;re normal &lt;code&gt;.org&lt;/code&gt; note files in a &lt;code&gt;dailies/&lt;/code&gt; directory, they have names like &lt;code&gt;2022-03-11.org&lt;/code&gt;. When I&amp;rsquo;m on an Org-roam page for a person, the majority of backlinks are to daily notes files. The backlinks become a record of when I talked to this person, and about what.&lt;/p&gt;
&lt;h2 id=&#34;navigating-to-daily-notes&#34;&gt;Navigating to daily notes&lt;/h2&gt;
&lt;p&gt;My Emacs configuration has the following keyboard shortcuts for navigating between Org-roam daily files quickly.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;key coord&lt;/th&gt;
          &lt;th&gt;function&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;SPC n r d t&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;org-roam-dailies-goto-today&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;SPC n r d y&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;org-roam-dailies-goto-yesterday&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;SPC n r d m&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;org-roam-dailies-goto-tomorrow&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;SPC n r d d&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;org-roam-dailies-goto-date&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Most often I&amp;rsquo;m using &lt;code&gt;SPC n r d t&lt;/code&gt; as a quick means to snap back to the notes I have for the current day. In the morning, it is usually helpful to also flip to what happened yesterday with &lt;code&gt;SPC n r d y&lt;/code&gt;. When the day is winding down, &lt;code&gt;SPC n r d m&lt;/code&gt; helps me write things down that apply to my schedule tomorrow. In order to see what happened on a particular date, I will use &lt;code&gt;SPC n r d d&lt;/code&gt;. It pops up a calendar buffer that can be used to navigate to any date you&amp;rsquo;re interested in.&lt;/p&gt;
&lt;h2 id=&#34;quick-capture-to-daily-notes&#34;&gt;Quick capture to daily notes&lt;/h2&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;key coord&lt;/th&gt;
          &lt;th&gt;function&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;SPC n r d T&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;org-roam-dailies-capture-today&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;SPC n r d Y&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;org-roam-dailies-capture-yesterday&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;SPC n r d M&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;org-roam-dailies-capture-tomorrow&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;SPC n r d D&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;org-roam-dailies-capture-date&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;These commands will make a new entry in the target daily file but will not navigate to the buffer when complete. They are a good way to capture a note without leaving your current location. I use &lt;code&gt;SPC n r d D&lt;/code&gt; to capture entries for a future date. If I have a presentation in a week, and I already have my speaking notes prepared, I&amp;rsquo;ll copy my speaking notes and use &lt;code&gt;SPC n r d D&lt;/code&gt; / &lt;code&gt;org-roam-dailies-capture-date&lt;/code&gt; to make an entry for the presentation on that day.&lt;/p&gt;
&lt;h2 id=&#34;meeting-capture-templates&#34;&gt;Meeting capture templates&lt;/h2&gt;
&lt;p&gt;Reiterating from above, what I find useful in my personal notes is to capture who the meeting attendees were, any links relevant to the meeting, a summary of some main talking points, and any action required to-do items. I find it helpful to use an org capture template for meeting notes to keep them consistent and easy to scan.&lt;/p&gt;
&lt;p&gt;&lt;span class=&#34;underline&#34;&gt;capture_templates/meeting.org&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;font-weight:bold&#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;font-weight:bold&#34;&gt;**&lt;/span&gt; Links
&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;font-weight:bold&#34;&gt;**&lt;/span&gt; Attendees
&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;font-weight:bold&#34;&gt;**&lt;/span&gt; Notes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;**&lt;/span&gt; Summary
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;**&lt;/span&gt; ARs [0/1]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;***&lt;/span&gt; TODO
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To use it, the template needs to be added to the &lt;code&gt;org-capture-templates&lt;/code&gt; list.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(use-package! org
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  :config
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (setq org-capture-templates
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &amp;#39;((&lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;n&amp;#34;&lt;/span&gt; &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;Meeting note&amp;#34;&lt;/span&gt; entry
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (file buffer-name)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (file &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;capture_templates/meeting.org&amp;#34;&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;My typical flow:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Jump to today&amp;rsquo;s daily file with &lt;code&gt;SPC n r d t&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Do &lt;code&gt;SPC X n&lt;/code&gt; to capture an entry for the new meeting.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;Select a capture template
=========================

[n]    Meeting note
----------------------------------
[q]    Abort
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Write in the name and purpose of the meeting&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Start doing Org-roam links for attendees and relevant topics&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;​* My important meeting
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;**&lt;/span&gt; Links
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;​   - https:/&lt;span style=&#34;font-style:italic&#34;&gt;/some-link-to-whatever.com
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;​   - https:/&lt;/span&gt;/docs.google.com/some-gdoc-for-meeting
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;**&lt;/span&gt; Attendees
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;​   - Paul
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;**&lt;/span&gt; Notes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;**&lt;/span&gt; Summary
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;**&lt;/span&gt; ARs [0/1]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;***&lt;/span&gt; TODO
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Capture it into the dailies file with &lt;code&gt;C-c C-c&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;review-and-grooming&#34;&gt;Review and grooming&lt;/h2&gt;
&lt;p&gt;My days are full of meetings and I have to bounce from one to the next. There is no time to reflect on notes, clean them up for future use, or make sure I take action on the results. When I have 5 m, or at the end of a day, I review my daily notes to underline important parts, add connective links, and create action items in my to-do tracking inbox. When I adhere to this practice I find that a lot fewer things slip through the cracks and I get better use out of my notes later.&lt;/p&gt;
&lt;h2 id=&#34;more-in-this-series&#34;&gt;More in this series&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;VP of Emacs&lt;/em&gt; series&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://willvaughn.org/articles/vp-of-emacs-a-personal-wiki-in-plain-text/&#34;&gt;VP of Emacs: A Personal Wiki in Plain Text&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks for reading, be well.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>VP of Emacs: A Personal Wiki In Plain Text</title>
      <link>http://willvaughn.org/articles/vp-of-emacs-a-personal-wiki-in-plain-text/</link>
      <pubDate>Wed, 05 Jan 2022 10:40:00 -0800</pubDate>
      
      <guid>http://willvaughn.org/articles/vp-of-emacs-a-personal-wiki-in-plain-text/</guid>
      <description>&lt;p&gt;&lt;em&gt;VP of Emacs&lt;/em&gt; is a blog series about using Emacs as an essential tool in my job as the VP of Software Engineering at Carbon Lighthouse. I&amp;rsquo;m a software engineer trying to cut it in a job that has required me to be more organized, communicative, strategic, and personal than ever. Emacs helps me get more done and keep it all connected. It has become the application I use everyday to unify note taking, emails, task management, writing, programming, and more.&lt;/p&gt;
&lt;p&gt;Watch the &lt;a href=&#34;https://youtu.be/qJhlHmDj7BI&#34;&gt;YouTube video&lt;/a&gt; that accompanys this blog.&lt;/p&gt;
&lt;h2 id=&#34;a-personal-wiki-with-org-and-org-roam&#34;&gt;A personal wiki with Org and Org-roam&lt;/h2&gt;
&lt;p&gt;A realization I had when I started doing software management was that I could no longer safely forget something and expect someone else to keep track of it. As a manager, I am the one expected to keep track of things. I don&amp;rsquo;t naturally multitask well, and when something is out of my sight it is well and truly out of my mind. If I were to have a chance at being a supportive and effective manager I knew I would need to find a way to augment my brain with something slightly addictive to use. When I first fired up an Org buffer I knew I had found a tool that appealed to my hacker nature in a way that would keep me coming back. Sometimes Emacs demands my attention and focus, I get sidetracked by a configuration tweak or technical fidgeting, but most of the time Emacs is a net-positive influence on my productivity.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://orgmode.org/&#34;&gt;Org&lt;/a&gt; is a plain-text file format for taking structured notes, as well as an Emacs mode that adds astonishing functionality for editing and interacting with &lt;code&gt;.org&lt;/code&gt; files. Org is one of the &amp;ldquo;killer apps&amp;rdquo; for Emacs, it&amp;rsquo;s widely used and well supported. Most of my work revolves around Org in some way or another. If you haven&amp;rsquo;t ever used &lt;code&gt;org-mode&lt;/code&gt;, I&amp;rsquo;d encourage you to get a feel for it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://orgmode.org/manual/&#34;&gt;Org Manual&lt;/a&gt;, a good place to go.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://orgmode.org/worg/org-tutorials/&#34;&gt;Org tutorials&lt;/a&gt;, curated org tutorial resources. Pick and choose what looks interesting to you, but I recommend beginning with the &lt;a href=&#34;https://www.youtube.com/playlist?list=PLVtKhBrRV%5FZkPnBtt%5FTD1Cs9PJlU0IIdE&#34;&gt;Rainer König video tutorials&lt;/a&gt; so you can see it in action quickly.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/JWD1Fpdd4Pc&#34;&gt;Evil Mode: Or, How I Learned to Stop Worrying and Love Emacs&lt;/a&gt;, is a conversion resource for vim lover.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Built on Org&amp;rsquo;s powerful base, lies &lt;a href=&#34;https://www.orgroam.com/&#34;&gt;Org-roam&lt;/a&gt;, a knowledge management system based on the features and approach of a proprietary research tool called &lt;a href=&#34;https://roamresearch.com/&#34;&gt;Roam Research&lt;/a&gt;. Org-roam transforms a folder of disconnected &lt;code&gt;.org&lt;/code&gt; files into a connected wiki and database of personal knowledge. Some people call this approach &amp;ldquo;building a second brain&amp;rdquo;, others refer to it as the &lt;a href=&#34;https://en.wikipedia.org/wiki/Zettelkasten&#34;&gt;Zettelkasten&lt;/a&gt; method. Whatever you call it, the result is being able to see connections between all of your notes that you couldn&amp;rsquo;t see before. Every page in roam has a list of &amp;ldquo;backlinks&amp;rdquo; to everywhere that page was mentioned. I&amp;rsquo;ll drive home the value of this as a software engineering manager with a simple but illustrative example.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;At any time, I can go to the Org-roam page for my CEO to see the details of any conversation or meeting I have had with him, ever.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;That doesn&amp;rsquo;t only apply to my CEO, that applies to everyone I work with. If we&amp;rsquo;ve had more than one conversation and done anything I might consider important business, you have an Org-roam page in my system.&lt;/p&gt;
&lt;p&gt;Tools like Evernote, Todoist, Superhuman, and Roam Research are enough to do anything I&amp;rsquo;ll write about in this blog series, but there are benefits I like about this plain-text approach to note taking that you don&amp;rsquo;t get with any other app.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The data is mine. I own it. I store it. It&amp;rsquo;s easy to manage because it&amp;rsquo;s just a folder of text files.&lt;/li&gt;
&lt;li&gt;Any tool that works with plain-text, works with my notes. I can &lt;code&gt;cat&lt;/code&gt; out a note from the command line. I can run &lt;code&gt;grep&lt;/code&gt; or &lt;code&gt;rg&lt;/code&gt; to search over file names or content. I can encrypt it if I want to with &lt;code&gt;gpg&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Storage space for plain-text files is minuscule.&lt;/li&gt;
&lt;li&gt;Text is portable. If Emacs ceased to exist, I could still edit and read my notes just fine using any other text editor.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;everyone-and-every-thing-gets-their-own-org-roam-note&#34;&gt;Everyone and every thing gets their own &lt;code&gt;org-roam&lt;/code&gt; note&lt;/h2&gt;
&lt;p&gt;Everyone I work with has an Org-roam note that becomes the central hub of information I have about them. People are the most significant part of my system, but they aren&amp;rsquo;t the only thing I keep track of.&lt;/p&gt;
&lt;p&gt;I have notes by topic:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Python&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Management&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Budgeting&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I keep notes for particular projects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;2021 Budget&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;2021Q3 Software Engineer Hiring&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Some Cleverly Named Internal Project&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;JIRA-123 TITLE&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I have notes for books I read, blogs I frequent, etc:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Systemcrafters&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Linux Command Line and Shell Scripting Bible&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;The Phoenix Project&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And the departments in my Company:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Sales&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Marketing&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;HR&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The more completely I link related ideas, the better the graph of my knowledge becomes. I want to be able to see how all of these people, ideas, and resources relate to each other. The purpose of taking notes this way is to be able to recall and rediscover information when it is needed. The more linked, the easier my knowledge is to traverse. I try to set aside time a few minutes a day to quickly scan, groom, and link notes. I go deeper during my weekly review sessions, often moving notes around or inserting links between them.&lt;/p&gt;
&lt;p&gt;Here is what one of my buffers might look like for one of my direct reports.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;:PROPERTIES:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;:ID:       aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;:ROAM_ALIASES: Jane
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;:END:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;#+title&lt;/span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;: Jane Doe&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;Lead Software Engineer at Carbon Lighthouse
&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;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt; Contact&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;- &lt;/span&gt;Phone: 555-1234
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;- &lt;/span&gt;Email: jane.doe@carbonlighthouse.com
&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;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt; Personal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;- &lt;/span&gt;Her son is John Jr 3yo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;- &lt;/span&gt;She is an accomplished rock n&amp;#39; roll musician, drummer
&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;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt; Performance Reviews&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;**&lt;/span&gt; 2021H2 Data Gathering...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;**&lt;/span&gt; 2021H2 Performance Review...
&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;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt; 2021&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;**&lt;/span&gt; 2021-09 September
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;***&lt;/span&gt; 2021-09-15 Wednesday...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;***&lt;/span&gt; 2021-09-15 Wednesday...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;***&lt;/span&gt; 2021-09-29 Wednesday...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;**&lt;/span&gt; 2021-10 October
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;***&lt;/span&gt; 2021-10-06 Wednesday...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It contains contact information, some reminders of personal details, performance review notes, and a datetree of our one on one meetings. The one on one meetings are shown using a collapse feature of Org in order to hide their details. In addition to this information, the Org-roam buffer shows the list of backlinks to everywhere Jane has been linked. These two buffers alone give me a great jumping off point to contextualize how well Jane is doing in her role. I often have a record of feedback she&amp;rsquo;s given and received, links to project&amp;rsquo;s she&amp;rsquo;s working on, notes on her contributions to team meetings, and more.&lt;/p&gt;
&lt;h2 id=&#34;one-on-one-meetings&#34;&gt;One on one meetings&lt;/h2&gt;
&lt;p&gt;The one-on-one or &amp;ldquo;o3&amp;rdquo; is the most important meeting I have as a VP of Engineering. I schedule 30 minute meetings once a week with my direct reports and I have many bi-weekly, monthly or quarterly touch points with other people in my department and around the company. Even though these meetings are somewhat informal and loosely structured I still treat them seriously. I rarely cancel them, and if I do then I&amp;rsquo;m sure to reschedule promptly. Because these meetings are so meaningful I like to be reasonably prepared for them, but I don&amp;rsquo;t usually take more than 5-10 minutes to prep. When I know I have an o3 coming up with a person I will navigate to their Org-roam file and run a specialized o3 &lt;code&gt;org-capture&lt;/code&gt; template to make a new entry in their datetree.&lt;/p&gt;
&lt;p&gt;Here is the simple template &lt;code&gt;org/capture_templates/o3.org&lt;/code&gt; with an agenda for me to fill in with my items before the meeting and to record anything that comes up during the meeting.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt; Direct (10m)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt; Manager (10m)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#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;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt; Future (10m)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt; ARs [/]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If today is Wednesday, Jan. 05 and I navigate to Jane&amp;rsquo;s file in preparation for an o3, I can type &lt;code&gt;SPC X o&lt;/code&gt; to automatically insert the template into that Jane&amp;rsquo;s datetree for today&amp;rsquo;s date.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt; 2021&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;**&lt;/span&gt; 2021-09 September
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;***&lt;/span&gt; 2021-09-15 Wednesday...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;***&lt;/span&gt; 2021-09-15 Wednesday...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;***&lt;/span&gt; 2021-09-29 Wednesday...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;**&lt;/span&gt; 2021-10 October
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;***&lt;/span&gt; 2021-10-06 Wednesday...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt; 2022&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;**&lt;/span&gt; 2022-01 January
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;***&lt;/span&gt; 2022-01-05 Wednesday
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;****&lt;/span&gt; Direct (10m)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;****&lt;/span&gt; Manager (10m)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;- &lt;/span&gt;Type something here
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;****&lt;/span&gt; Future (10m)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;****&lt;/span&gt; ARs [/]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above can also be done on Monday, Jan. 03 in preparation for a meeting that happens Wednesday by typing &lt;code&gt;SPC u 1 SPC X o&lt;/code&gt;. This version of the command prompts the user for a date before inserting the template into the file.&lt;/p&gt;
&lt;p&gt;This is a &lt;a href=&#34;https://orgmode.org/manual/Capture.html&#34;&gt;capture&lt;/a&gt; customization of Emacs and Org that helps me do something specific to my particular workflow. All it takes is a little Emacs Lisp.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(use-package! org
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  :config
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (setq org-capture-templates
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &amp;#39;((&lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;o&amp;#34;&lt;/span&gt; &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;o3&amp;#34;&lt;/span&gt; entry
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (file+olp+datetree buffer-name)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (file &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;capture_templates/o3.org&amp;#34;&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This change sets some options that inform Org how to do all the heavy lifting. Maybe this is something you could imagine seeing in the preferences menu of your favorite note taking application. However, this is quite different than that because of what it reveals, that Emacs is configured by the elisp programming language. Emacs can be thought of as an elisp interpreter or framework for building applications, especially applications that involve text processing. In the long-term this is the most important feature of Emacs, it unlocks the power for every individual to make Emacs into whatever they want it to be. If that&amp;rsquo;s intriguing to you, I hope you&amp;rsquo;ll keep reading as I lay out more of the ways I am weaving my software organization management philosophy into Emacs.&lt;/p&gt;
&lt;h2 id=&#34;coming-up-next&#34;&gt;Coming up next&lt;/h2&gt;
&lt;p&gt;Some of the things I have in mind to write more about are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How I take meeting notes leveraging Org-roam&amp;rsquo;s &amp;ldquo;dailies&amp;rdquo; features, to have even more information about who I talked to, when, and about what.&lt;/li&gt;
&lt;li&gt;The task management capabilities of Org and Org Agenda, and how I use them to store every idea that pops into my head, deferring them for later action without getting sidetracked.&lt;/li&gt;
&lt;li&gt;Reading my email from Emacs with a tool called &amp;ldquo;notmuch&amp;rdquo;, and how I seamlessly integrate action items that arise from email with my other tasks. I can reference emails from any note to provide more context for anything I&amp;rsquo;m thinking about. All without ever leaving Emacs.&lt;/li&gt;
&lt;li&gt;Sharing my notes in Google Docs, Markdown, PDF, HTML, or any other easily exportable target for the export features of Org.&lt;/li&gt;
&lt;li&gt;How I connect to PostgreSQL to run queries from Emacs in order to generate metrics reports on my Team and our software product.&lt;/li&gt;
&lt;li&gt;How I perform objective and data-centric performance reviews based on the information I can access about my team in Emacs and other tools.&lt;/li&gt;
&lt;li&gt;And all the other things I learn how to do in 2022.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I hope I&amp;rsquo;ll see you around.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Moving to sourcehut</title>
      <link>http://willvaughn.org/articles/moving-to-sourcehut/</link>
      <pubDate>Sat, 04 Dec 2021 23:53:00 -0800</pubDate>
      
      <guid>http://willvaughn.org/articles/moving-to-sourcehut/</guid>
      <description>&lt;p&gt;Sourcehut recently announced their new &lt;a href=&#34;https://chat.sr.ht&#34;&gt;chat.sr.ht&lt;/a&gt; service to provide an IRC bouncer server for all paying members. You can read more about the launch on &lt;a href=&#34;https://sourcehut.org/blog/2021-11-29-announcing-the-chat.sr.ht-public-beta/&#34;&gt;sourcehut&amp;rsquo;s blog&lt;/a&gt;. I&amp;rsquo;ve been running my own ZNC bouncer, but it broke and I haven&amp;rsquo;t got around to fixing it. As a result, I haven&amp;rsquo;t been using as much IRC. I&amp;rsquo;ve been looking to the release of chat.sr.ht as a way to get back into it. I use Emacs as my IRC client, and it took me one night of fiddling to get it working with the new Soju bouncer. The chat.sr.ht service requires login via SASL. The built-in ERC client in Emacs does not support SASL logins. I decided to use &lt;a href=&#34;https://github.com/emacs-circe/circe&#34;&gt;Circe&lt;/a&gt; instead. Below is a configuration that has been working well.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(use-package! circe
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  :config
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (setq circe-network-options
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        `((&lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;Libera&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           :tls t
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           :nick &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;nackjicholson&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           :host &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;chat.sr.ht&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           :port 6697
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;font-style:italic&#34;&gt;;; For security purposes pulling these from an encrypted secrets file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           :sasl-username &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;willvaughn/libera@my-client&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           :sasl-password &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;...sr.ht oauth token...&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        circe-reduce-lurker-spam t))
&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;(use-package! circe-color-nicks
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  :config
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (enable-circe-color-nicks))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This service pushed me over the edge toward really trying sourcehut, and it&amp;rsquo;s great. I&amp;rsquo;m going to bring my projects onto the platform. This blog is now using &lt;a href=&#34;https://srht.site/&#34;&gt;https://srht.site/&lt;/a&gt; for static web hosting. It was a painless migration. I&amp;rsquo;m planning to move many of my personal repos over to sourcehut. I will likely keep popular projects like &lt;a href=&#34;https://github.com/nackjicholson/aiosql&#34;&gt;aiosql&lt;/a&gt; where they are in order to not be too disruptive to the community already using them. One of the things that really attracts me to sourcehut is their business philosophy and uncompromising pursuit of being a truly open source first platform.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://sourcehut.org/blog/2019-10-23-srht-puts-users-first/&#34;&gt;Our model is customers first, investors never&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://sourcehut.org/blog/2021-01-13-regarding-ethics/&#34;&gt;On the subject of ethics in our industry&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I also love their willingness to dispense with the status quo and push their users to change their habits and adapt to simpler and established tooling that works better for everyone.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://git-send-email.io/&#34;&gt;https://git-send-email.io/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://git-rebase.io/&#34;&gt;https://git-rebase.io/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://useplaintext.email/&#34;&gt;https://useplaintext.email/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I hope I&amp;rsquo;ll see your projects on sourcehut. Please come contribute on mine!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>PyPA Python Packaging User Guide Review</title>
      <link>http://willvaughn.org/articles/pypa-python-packaging-user-guide-review/</link>
      <pubDate>Thu, 29 Jul 2021 19:26:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/pypa-python-packaging-user-guide-review/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://packaging.python.org/&#34;&gt;Python Packaging User Guide&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Python is incredible, but the packaging story is a pain point even for programmers with years of experience. These docs are worth reading slowly, allowing yourself to follow links and get a sense for what is at your disposal for package and distribution management. The core of this documentation is about how to use &lt;code&gt;pip&lt;/code&gt;, &lt;code&gt;setuptools&lt;/code&gt;, &lt;code&gt;build&lt;/code&gt;, and &lt;code&gt;python -m venv&lt;/code&gt; to great effect. Many of us aren&amp;rsquo;t as familiar with these basic tools as we should be. We&amp;rsquo;ve jumped away for abstractions that add layers of insulation between us and these basic tools before really trying in earnest to use them.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://virtualenv.pypa.io/&#34;&gt;virtualenv&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pypi.org/project/virtualenvwrapper/&#34;&gt;virtualenvwrapper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://python-poetry.org/&#34;&gt;Poetry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pipenv.pypa.io/en/latest/&#34;&gt;Pipenv&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://dephell.readthedocs.io/&#34;&gt;dephell&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I used Poetry for a long time in my open source project &lt;a href=&#34;https://githbub.com/nackjicholson/aiosql/&#34;&gt;aiosql&lt;/a&gt;, but after reading this PyPA documentation I switched to the basics. Someone should be able to download my code and run something as simple as &lt;code&gt;pip install .&lt;/code&gt; or &lt;code&gt;pip install -r dev-requirements.txt&lt;/code&gt; to get going. Using &lt;code&gt;poetry&lt;/code&gt; was putting a burden on people who pick up the project and want to collaborate with me. I&amp;rsquo;m not saying not to use &lt;code&gt;poetry&lt;/code&gt;. I think it has the best user experience and is the smartest of any tool available to the python developer. If your application team, working out of a private repository, has discussed and decided to align on using poetry and everything that comes with it, great. But, read the PyPA packaging guide anyway, because you might learn that the basic tools do what you want, are well supported, and don&amp;rsquo;t have as bad a UX as you thought.&lt;/p&gt;
&lt;h2 id=&#34;highlights&#34;&gt;Highlights&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/jazzband/pip-tools&#34;&gt;pip-tools&lt;/a&gt; is the minimal layer of extra tooling to pin dependencies for build reproducability that you actually need.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;setup.cfg&lt;/code&gt; exists and should be used for as much as possible before you write a single line to a &lt;code&gt;setup.py&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;a good explanation of what &lt;code&gt;sdist&lt;/code&gt; and &lt;code&gt;wheel&lt;/code&gt; packages are.&lt;/li&gt;
&lt;li&gt;Links to a lot of PEPs.&lt;/li&gt;
&lt;li&gt;All the ways to deploy and distribute a Python application, with examples and trade-offs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks for reading, see you out there in the source code.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>IRC Services at Home with k3s</title>
      <link>http://willvaughn.org/articles/irc-services-at-home-with-k3s/</link>
      <pubDate>Tue, 27 Jul 2021 19:47:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/irc-services-at-home-with-k3s/</guid>
      <description>&lt;p&gt;This is a follow-on to my previous two blogs about running ZNC and Bitlbee in k3s/Docker.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://willvaughn.org/articles/running-znc-bouncer-with-k3s&#34;&gt;Running ZNC Bouncer with k3s&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://willvaughn.org/articles/running-bitlbee-and-signald-with-docker&#34;&gt;Running Bitlbee &amp;amp; Signald with Docker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In my prior k3s blog I ran a &lt;code&gt;NodePort&lt;/code&gt; Kubernetes Service because I was unable to figure out how to get an Ingress setup and how to run ZNC behind a reverse proxy. I&amp;rsquo;ve figured that out now. It wasn&amp;rsquo;t entirely simple because there were a few non-obvious things that needed to be undestood.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;IRC needs to be proxied via TCP not HTTP, and ZNC should take that traffic separately.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://wiki.znc.in/Reverse_Proxy#Traefik&#34;&gt;ZNC Wiki - Revers Proxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://doc.traefik.io/traefik/routing/providers/kubernetes-crd/#kind-ingressroutetcp&#34;&gt;Traefik IngressRouteTCP&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Host Server Name Indication (HostSNI) only works if you&amp;rsquo;re using TLS, so routing by subdomains only works if you&amp;rsquo;re bothering with SSL/TLS.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://doc.traefik.io/traefik/routing/routers/#entrypoints_1&#34;&gt;Traefik Endpoints&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ZNC Configuration for URIPrefix allows ZNC&amp;rsquo;s webadmin to serve assets while behind a reverse proxy
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://wiki.znc.in/Configuration#Listener&#34;&gt;URIPrefix&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The way to configure k3s addons like Traefik, is to drop their configuration in a server folder.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://rancher.com/docs/k3s/latest/en/advanced/#auto-deploying-manifests&#34;&gt;k3s - Auto Deploying Manifests&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Subdomains on a local network with mDNS is possible but not easy, and you should get on with your life. Edit your &lt;code&gt;/etc/hosts&lt;/code&gt; my friend.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;192.168.X.Y znc.vault.local bee.vault.local&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here&amp;rsquo;s what I have now. I&amp;rsquo;m using a Protectli Vault Mini-PC but I believe this whole thing could easily be run on a raspbery pi or whatever else you have lying around the house. :)&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;http://willvaughn.org/images/irc-services-with-k3s/k3s-irc.png&#34;&gt;
&lt;/figure&gt;

&lt;p&gt;The steps described in detail in my previous two blogs will still be helpful in getting the services configured and initialized. Rather than repeat it all again, I&amp;rsquo;m going to share the YAML and let you explore. Feel free to ask me questions if you&amp;rsquo;re trying to setup something similar for yourself.&lt;/p&gt;
&lt;h2 id=&#34;var-lib-rancher-k3s-server-manifests-traefik-dot-yaml&#34;&gt;/var/lib/rancher/k3s/server/manifests/traefik.yaml&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;: helm.cattle.io/v1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: HelmChart
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: traefik-crd
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;namespace&lt;/span&gt;: kube-system
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;chart&lt;/span&gt;: https://%{KUBERNETES_API}%/static/charts/traefik-crd-9.18.2.tgz
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#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;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;: helm.cattle.io/v1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: HelmChart
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: traefik
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;namespace&lt;/span&gt;: kube-system
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;chart&lt;/span&gt;: https://%{KUBERNETES_API}%/static/charts/traefik-9.18.2.tgz
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;set&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;global.systemDefaultRegistry&lt;/span&gt;: &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;&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;font-weight:bold&#34;&gt;valuesContent&lt;/span&gt;: |-&lt;span style=&#34;font-style:italic&#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;font-style:italic&#34;&gt;    rbac:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;      enabled: true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;    ports:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;      bee-irc:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;        port: 6665
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;        expose: true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;        expoosedPort: 6665
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;        protocol: TCP
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;      znc-irc:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;        port: 6667
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;        expose: true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;        exposedPort: 6667
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;        protocol: TCP
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;      websecure:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;        tls:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;          enabled: true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;    podAnnotations:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;      prometheus.io/port: &amp;#34;8082&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;font-style:italic&#34;&gt;      prometheus.io/scrape: &amp;#34;true&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;font-style:italic&#34;&gt;    providers:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;      kubernetesIngress:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;        publishedService:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;          enabled: true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;    priorityClassName: &amp;#34;system-cluster-critical&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;font-style:italic&#34;&gt;    image:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;      name: &amp;#34;rancher/library-traefik&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;font-style:italic&#34;&gt;    tolerations:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;    - key: &amp;#34;CriticalAddonsOnly&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;font-style:italic&#34;&gt;      operator: &amp;#34;Exists&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;font-style:italic&#34;&gt;    - key: &amp;#34;node-role.kubernetes.io/control-plane&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;font-style:italic&#34;&gt;      operator: &amp;#34;Exists&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;font-style:italic&#34;&gt;      effect: &amp;#34;NoSchedule&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;font-style:italic&#34;&gt;    - key: &amp;#34;node-role.kubernetes.io/master&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;font-style:italic&#34;&gt;      operator: &amp;#34;Exists&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;font-style:italic&#34;&gt;      effect: &amp;#34;NoSchedule&amp;#34;&lt;/span&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;traefik-ingress-base-routes-dot-yaml&#34;&gt;traefik-ingress/base/routes.yaml&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#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;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;: traefik.containo.us/v1alpha1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: IngressRouteTCP
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc-routes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;namespace&lt;/span&gt;: default
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;entryPoints&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - znc-irc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;routes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: Rule
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;match&lt;/span&gt;: HostSNI(`*`)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;services&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - &lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: Service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc-bouncer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;namespace&lt;/span&gt;: default
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;port&lt;/span&gt;: 6667
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#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;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;: traefik.containo.us/v1alpha1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: IngressRouteTCP
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: bee-routes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;namespace&lt;/span&gt;: default
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;entryPoints&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - bee-irc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;routes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: Rule
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;match&lt;/span&gt;: HostSNI(`*`)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;services&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - &lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: Service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: bitlbee
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;namespace&lt;/span&gt;: default
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;port&lt;/span&gt;: 6667
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#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;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;: traefik.containo.us/v1alpha1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: IngressRoute
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: web-routes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;namespace&lt;/span&gt;: default
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;entryPoints&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - web
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;routes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: Rule
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;match&lt;/span&gt;: Host(`vault.local`) &amp;amp;&amp;amp; PathPrefix(`/znc/`)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;services&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - &lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: Service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc-bouncer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;namespace&lt;/span&gt;: default
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;port&lt;/span&gt;: 8888
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;bitlbee-base-service-dot-yaml&#34;&gt;bitlbee/base/service.yaml&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#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;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;: v1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: Service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;labels&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;app&lt;/span&gt;: bitlbee
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: bitlbee
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;ports&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: bitlbee-irc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;port&lt;/span&gt;: 6667
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;protocol&lt;/span&gt;: TCP
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;targetPort&lt;/span&gt;: 6667
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;selector&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;app&lt;/span&gt;: bitlbee
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;type&lt;/span&gt;: ClusterIP
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;bitlbee-base-pvc-bitlbee-dot-yaml&#34;&gt;bitlbee/base/pvc-bitlbee.yaml&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#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;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;: v1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: PersistentVolumeClaim
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: bitlbee-local-path-pvc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;namespace&lt;/span&gt;: default
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;accessModes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - ReadWriteOnce
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;storageClassName&lt;/span&gt;: local-path
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;resources&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;requests&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;storage&lt;/span&gt;: 1000Ki
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;bitlbee-base-pvc-signald-dot-yaml&#34;&gt;bitlbee/base/pvc-signald.yaml&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#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;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;: v1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: PersistentVolumeClaim
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: signald-local-path-pvc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;namespace&lt;/span&gt;: default
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;accessModes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - ReadWriteOnce
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;storageClassName&lt;/span&gt;: local-path
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;resources&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;requests&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;storage&lt;/span&gt;: 1000Ki
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;bitlbee-base-deployment-dot-yaml&#34;&gt;bitlbee/base/deployment.yaml&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#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;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;: apps/v1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: Deployment
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;labels&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;app&lt;/span&gt;: bitlbee
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: bitlbee
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;replicas&lt;/span&gt;: 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;selector&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;matchLabels&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;app&lt;/span&gt;: bitlbee
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;template&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;labels&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;app&lt;/span&gt;: bitlbee
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;volumes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: bitlbee-data
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;persistentVolumeClaim&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;font-weight:bold&#34;&gt;claimName&lt;/span&gt;: bitlbee-local-path-pvc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: signald-socket
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;persistentVolumeClaim&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;font-weight:bold&#34;&gt;claimName&lt;/span&gt;: signald-local-path-pvc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;initContainers&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: volume-mount-hack
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;image&lt;/span&gt;: ezkrg/bitlbee-libpurple:latest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;command&lt;/span&gt;: [&lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;sh&amp;#34;&lt;/span&gt;, &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;-c&amp;#34;&lt;/span&gt;, &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;chmod -R 777 /var/lib/bitlbee &amp;amp;&amp;amp; chmod -R 777 /var/run/signald&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;font-weight:bold&#34;&gt;volumeMounts&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        - &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: bitlbee-data
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;font-weight:bold&#34;&gt;mountPath&lt;/span&gt;: /var/lib/bitlbee
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        - &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: signald-socket
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;font-weight:bold&#34;&gt;mountPath&lt;/span&gt;: /var/run/signald
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;containers&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: signald
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;image&lt;/span&gt;: finn/signald:latest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;volumeMounts&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          - &lt;span style=&#34;font-weight:bold&#34;&gt;mountPath&lt;/span&gt;: /signald
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: signald-socket
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: bitlbee
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;image&lt;/span&gt;: ezkrg/bitlbee-libpurple:latest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;ports&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        - &lt;span style=&#34;font-weight:bold&#34;&gt;containerPort&lt;/span&gt;: 6667
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;volumeMounts&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          - &lt;span style=&#34;font-weight:bold&#34;&gt;mountPath&lt;/span&gt;: /var/run/signald
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: signald-socket
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          - &lt;span style=&#34;font-weight:bold&#34;&gt;mountPath&lt;/span&gt;: /var/lib/bitlbee
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: bitlbee-data
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;znc-base-service-dot-yaml&#34;&gt;znc/base/service.yaml&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#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;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;: v1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: Service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;labels&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;app&lt;/span&gt;: znc-bouncer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc-bouncer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;ports&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc-irc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;port&lt;/span&gt;: 6667
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;protocol&lt;/span&gt;: TCP
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;targetPort&lt;/span&gt;: 6667
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc-webadmin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;port&lt;/span&gt;: 8888
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;protocol&lt;/span&gt;: TCP
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;targetPort&lt;/span&gt;: 8888
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;selector&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;app&lt;/span&gt;: znc-bouncer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;type&lt;/span&gt;: ClusterIP
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;znc-base-pvc-dot-yaml&#34;&gt;znc/base/pvc.yaml&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#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;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;: v1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: PersistentVolumeClaim
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc-local-path-pvc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;namespace&lt;/span&gt;: default
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;accessModes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - ReadWriteOnce
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;storageClassName&lt;/span&gt;: local-path
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;resources&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;requests&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;storage&lt;/span&gt;: 200Ki
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;znc-base-deployment-dot-yaml&#34;&gt;znc/base/deployment.yaml&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#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;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;: apps/v1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: Deployment
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;labels&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;app&lt;/span&gt;: znc-bouncer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc-bouncer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;replicas&lt;/span&gt;: 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;selector&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;matchLabels&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;app&lt;/span&gt;: znc-bouncer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;template&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;labels&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;app&lt;/span&gt;: znc-bouncer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;volumes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc-config
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;persistentVolumeClaim&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;font-weight:bold&#34;&gt;claimName&lt;/span&gt;: znc-local-path-pvc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;initContainers&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: init-config
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;image&lt;/span&gt;: znc:1.8.2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;command&lt;/span&gt;: [&lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;/bin/sh&amp;#39;&lt;/span&gt;, &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;-c&amp;#39;&lt;/span&gt;, &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;until [ -f /znc-data/configs/znc.conf ]; do echo waiting for znc.conf; sleep 2; done&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;font-weight:bold&#34;&gt;volumeMounts&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          - &lt;span style=&#34;font-weight:bold&#34;&gt;mountPath&lt;/span&gt;: /znc-data
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc-config
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;containers&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;image&lt;/span&gt;: znc:1.8.2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;ports&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        - &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc-irc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;font-weight:bold&#34;&gt;containerPort&lt;/span&gt;: 6667
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        - &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc-webadmin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;font-weight:bold&#34;&gt;containerPort&lt;/span&gt;: 8888
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;volumeMounts&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          - &lt;span style=&#34;font-weight:bold&#34;&gt;mountPath&lt;/span&gt;: /znc-data
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc-config
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;znc-webadmin-listeners&#34;&gt;ZNC Webadmin Listeners&lt;/h2&gt;
&lt;figure&gt;&lt;img src=&#34;http://willvaughn.org/images/irc-services-with-k3s/znc-listeners.png&#34;&gt;
&lt;/figure&gt;

</description>
    </item>
    
    <item>
      <title>Running Bitlbee &amp; Signald with Docker</title>
      <link>http://willvaughn.org/articles/running-bitlbee-and-signald-with-docker/</link>
      <pubDate>Mon, 26 Jul 2021 02:48:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/running-bitlbee-and-signald-with-docker/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://www.bitlbee.org/main.php/news.r.html&#34;&gt;Bitlbee&lt;/a&gt; is an IRC server which bridges to other common chat applications. I use it to text my friends on &lt;a href=&#34;https://www.signal.org/&#34;&gt;Signal&lt;/a&gt; from an Emacs ERC buffer. It&amp;rsquo;s possible to run bitlbee as a Docker container and systemd service on your personal Linux system, that&amp;rsquo;s what this blog will show you how to do.&lt;/p&gt;
&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;In order for Bitlbee to work with Signal, you need some libraries, &lt;a href=&#34;https://signald.org/&#34;&gt;signald&lt;/a&gt; and &lt;a href=&#34;https://github.com/hoehermann/libpurple-signald&#34;&gt;libpurple-signald&lt;/a&gt;. The libpurple library is a common requirement for many bitlbee bridges, and fortunately there is already a suitable docker container with bitlbee and libpurple pre-installed, &lt;a href=&#34;https://github.com/ezkrg/docker-bitlbee-libpurple&#34;&gt;ezkrg/bitlbee-libpurple&lt;/a&gt;. However, it does not have signald installed in it. We will need to run another container, &lt;a href=&#34;https://git.callpipe.com/finn/signald&#34;&gt;finn/signald&lt;/a&gt;, and give the bitlbee container access to it via a shared volume. Once the containers are set and available, we&amp;rsquo;ll use systemd to ensure they start on boot.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;#setup-storage-and-cross-communication-volumes&#34;&gt;Setup Storage &amp;amp; Cross Communication Volumes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#run-the-containers&#34;&gt;Run the Containers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#login-and-verify-device-with-signal&#34;&gt;Login &amp;amp; Verify Device with Signal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#create-a-systemd-user-unit&#34;&gt;Create a Systemd User Unit&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;setup-storage-and-cross-communication-volumes&#34;&gt;Setup Storage &amp;amp; Cross Communication Volumes&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;mkdir -p ~/.cache/docker-bitlbee/bitlbee
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir -p ~/.cache/docker-bitlbee/signald
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;chmod 777 ~/.cache/docker-bitlbee/bitlbee
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;chmod 777 ~/.cache/docker-bitlbee/signald
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;run-the-containers&#34;&gt;Run the Containers:&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;docker run &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    --name docker-signald.service &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    --detach &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    --restart=unless-stopped &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    -v ~/.cache/docker-bitlbee/signald/run:/signald &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    finn/signald
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker run &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    -p 6667:6667 &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    --name docker-bitlbee.service &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    --detach --restart=unless-stopped &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    -v ~/.cache/docker-bitlbee/bitlbee:/var/lib/bitlbee &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    -v ~/.cache/docker-bitlbee/signald/run:/var/run/signald &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    ezkrg/bitlbee-libpurple:latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;login-and-verify-device-with-signal&#34;&gt;Login &amp;amp; Verify Device with Signal&lt;/h2&gt;
&lt;p&gt;More official instructions are available at &lt;a href=&#34;https://github.com/hoehermann/libpurple-signald/blob/master/HOWTO.md&#34;&gt;libpurple-signald HOWTO.md&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Connect your IRC client to the bitlbee container. To do that with ERC in Emacs I can evaluate the following elisp.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(erc :server &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;localhost&amp;#34;&lt;/span&gt; :port 6667 :nick &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;willvaughn&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once connected, register the user.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;register &amp;lt;password&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then add the Signal bridge from the &lt;code&gt;&amp;amp;root&lt;/code&gt; channel.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;account add hehoe-signald +12223334444
account hehoe-signald set tag signal
account signal set auto-join-group-chats true
account signal set nick_format %full_name-sig
account signal on
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is going to fail and print out a &lt;code&gt;qrencode&lt;/code&gt; command. The docker container doesn&amp;rsquo;t have qrencode installed it. Until that is fixed, you can work around it by installing &lt;code&gt;qrencode&lt;/code&gt; on your system and running the failed command. The result will be a QR code image that you can scan in your signal phone app to verify the new signald device.&lt;/p&gt;
&lt;p&gt;For myself on Arch Linux, this is what I did:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;sudo pacman -S qrencode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;qrencode -s 6 -o /tmp/signald_link_purple_qrcode.png &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;tsdevice:/?uuid=yadayada&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;xdg-open /tmp/signald_link_purple_qrcode.png
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once you scan the QR code witht he Signal app on your phone, you should receive a logged in message in your IRC client.&lt;/p&gt;
&lt;p&gt;Finish configuration and enablement of the &lt;code&gt;&amp;amp;signal&lt;/code&gt; account/channel. See bitlbee docs on &lt;a href=&#34;https://wiki.bitlbee.org/ManagingContactList&#34;&gt;Managing contact lists&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;These are the channel settings I ran.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;channel &amp;amp;signal set account signal
channel &amp;amp;signal set fill_by account
channel &amp;amp;signal set auto_join true
rename _12223334444 myname-sig
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Save it (ends up in our shared docker volume so we don&amp;rsquo;t have to do this everytime we log in).&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;save
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;create-a-systemd-user-unit&#34;&gt;Create a Systemd User Unit&lt;/h2&gt;
&lt;p&gt;For more on how systemd works see &lt;a href=&#34;https://wiki.archlinux.org/title/Systemd/User#How_it_works&#34;&gt;Systemd/User - How It Works&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Make a signald service at &lt;code&gt;.config/systemd/user/docker-signald.service&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cfg&#34; data-lang=&#34;cfg&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;[Unit]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Description=&lt;span style=&#34;font-style:italic&#34;&gt;A signald container 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;font-weight:bold&#34;&gt;[Service]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Restart=&lt;span style=&#34;font-style:italic&#34;&gt;always&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ExecStart=&lt;span style=&#34;font-style:italic&#34;&gt;/usr/bin/docker start -a docker-signald.service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ExecStop=&lt;span style=&#34;font-style:italic&#34;&gt;/usr/bin/docker stop docker-signald.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;font-weight:bold&#34;&gt;[Install]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;WantedBy=&lt;span style=&#34;font-style:italic&#34;&gt;default.target&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Make the bitlbee service at &lt;code&gt;~/.config/systemd/user/docker-bitlbee.service&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cfg&#34; data-lang=&#34;cfg&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;[Unit]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Description=&lt;span style=&#34;font-style:italic&#34;&gt;A Bitlbee IRC bridge container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Wants=&lt;span style=&#34;font-style:italic&#34;&gt;docker-signald.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;font-weight:bold&#34;&gt;[Service]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Restart=&lt;span style=&#34;font-style:italic&#34;&gt;always&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ExecStart=&lt;span style=&#34;font-style:italic&#34;&gt;/usr/bin/docker start -a docker-bitlbee.service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ExecStop=&lt;span style=&#34;font-style:italic&#34;&gt;/usr/bin/docker stop docker-bitlbee.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;font-weight:bold&#34;&gt;[Install]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;WantedBy=&lt;span style=&#34;font-style:italic&#34;&gt;default.target&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Inform Systemd about these unit changes.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;systemctl --user daemon-reload
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Start the IRC service.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;systemctl --user  enable docker-signald.service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemctl --user  enable docker-signald.service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;That should do it. I hope this has helped you run bitlbee on your system.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Running ZNC Bouncer With K3s</title>
      <link>http://willvaughn.org/articles/running-znc-bouncer-with-k3s/</link>
      <pubDate>Sun, 25 Jul 2021 14:15:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/running-znc-bouncer-with-k3s/</guid>
      <description>&lt;p&gt;In my previous blog &lt;em&gt;&lt;a href=&#34;http://willvaughn.org/articles/my-personal-irc-renaissance&#34;&gt;My Personal IRC Renaissance&lt;/a&gt;&lt;/em&gt; I explained how and why I&amp;rsquo;ve recently started using IRC more. One of the things that I think keeps IRC relevant is its simplicity. The simplicity lends itself to hackability and experimentation. It&amp;rsquo;s great fun! The simplicity can also sometimes be a detriment. In our modern internet world we expect applications to store information and give it to us on-demand. IRC doesn&amp;rsquo;t work like that. It is as real-time as real-time gets. If you&amp;rsquo;re not logged in, you don&amp;rsquo;t see your messages. Running a &lt;a href=&#34;https://wiki.znc.in/ZNC&#34;&gt;ZNC&lt;/a&gt; Bouncer is one way to layer on some features to IRC that make it feel like a more modern application. ZNC stays logged into IRC for you, and you can connect to it from multiple IRC clients. The service buffes and replays messages you missed since your last connection.&lt;/p&gt;
&lt;p&gt;For a while I was running ZNC on a Google Cloud Platform VM. Instructions and resources for how to do so are &lt;a href=&#34;https://wiki.systemcrafters.cc/community/znc-bouncer-servers/&#34;&gt;here&lt;/a&gt;, on the System Crafters Wiki. This solution worked for me for about a month, but since I&amp;rsquo;m not using that server for anything else it&amp;rsquo;s quite a price tag to pay just to run a ZNC service. There are lots of cheaper hosting solutions, but I decided instead to run ZNC inside my local home network where it&amp;rsquo;s not exposed to the broader internet. This is also inexpensive because I&amp;rsquo;m leveraging a &lt;a href=&#34;https://protectli.com/vault-4-port/&#34;&gt;Protectli Vault Mini-PC&lt;/a&gt; that I already own which is acting as the master node of a small Kubernetes cluster via &lt;a href=&#34;https://k3s.io&#34;&gt;k3s&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Implementation
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#overview&#34;&gt;Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://willvaughn.org/#persistent-volume-for-znc-config&#34;&gt;Persistent Volume for ZNC Config&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#znc-deployment&#34;&gt;ZNC Deployment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#znc-nodeport-service&#34;&gt;ZNC NodePort Service&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#connecting-from-erc&#34;&gt;Connecting from ERC&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;implementation&#34;&gt;Implementation&lt;/h2&gt;
&lt;h3 id=&#34;overview&#34;&gt;Overview&lt;/h3&gt;
&lt;figure&gt;&lt;img src=&#34;http://willvaughn.org/images/znc-k3s/znc-k3s.png&#34;&gt;
&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; See my blog &lt;a href=&#34;http://willvaughn.org/articles/irc-services-at-home-with-k3s&#34;&gt;IRC Services at Home with k3s&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;persistent-volume-for-znc-config&#34;&gt;Persistent Volume for ZNC Config&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#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;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;: v1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: PersistentVolumeClaim
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc-local-path-pvc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;namespace&lt;/span&gt;: default
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;accessModes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - ReadWriteOnce
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;storageClassName&lt;/span&gt;: local-path
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;resources&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;requests&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;storage&lt;/span&gt;: 200Ki
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A &lt;a href=&#34;https://kubernetes.io/docs/concepts/storage/persistent-volumes/&#34;&gt;Persistent Volume&lt;/a&gt; holds data after a deployment or pod is gone. It is used here to supply a permanent location for the &lt;code&gt;/znc-data&lt;/code&gt; directory that the ZNC application works with. The ZNC webadmin itself interacts directly with a file &lt;code&gt;/znc-data/configs/znc.conf&lt;/code&gt;. This is like the database for ZNC. It holds all information about your servers, nicknames, and configured options. Because this is a dynamic config, it changes as you use the ZNC web app, it would be a poor fit for a k8s &lt;code&gt;configmap&lt;/code&gt; object. It needs to be updated while the pod runs. The PVC was the best solution I could come up with. Let me know if you come up with anything better!&lt;/p&gt;
&lt;h3 id=&#34;znc-deployment&#34;&gt;ZNC Deployment&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#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;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;: apps/v1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: Deployment
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;labels&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;app&lt;/span&gt;: znc-bouncer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc-bouncer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;replicas&lt;/span&gt;: 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;selector&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;matchLabels&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;app&lt;/span&gt;: znc-bouncer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;template&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;labels&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;app&lt;/span&gt;: znc-bouncer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;volumes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc-config
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;persistentVolumeClaim&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;font-weight:bold&#34;&gt;claimName&lt;/span&gt;: znc-local-path-pvc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;initContainers&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: init-config
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;image&lt;/span&gt;: znc:1.8.2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;command&lt;/span&gt;: [&lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;/bin/sh&amp;#39;&lt;/span&gt;, &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;-c&amp;#39;&lt;/span&gt;, &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;until [ -f /znc-data/configs/znc.conf ]; do echo waiting for znc.conf; sleep 2; done&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;font-weight:bold&#34;&gt;volumeMounts&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          - &lt;span style=&#34;font-weight:bold&#34;&gt;mountPath&lt;/span&gt;: /znc-data
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc-config
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;font-weight:bold&#34;&gt;containers&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;image&lt;/span&gt;: znc:1.8.2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;ports&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        - &lt;span style=&#34;font-weight:bold&#34;&gt;containerPort&lt;/span&gt;: 6667
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;font-weight:bold&#34;&gt;volumeMounts&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          - &lt;span style=&#34;font-weight:bold&#34;&gt;mountPath&lt;/span&gt;: /znc-data
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc-config
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Probably not the simplest deployment file you&amp;rsquo;ve seen. There&amp;rsquo;s a few things to go over here.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;volumes&lt;/code&gt; and &lt;code&gt;volumeMounts&lt;/code&gt; are staking a claim on our &lt;code&gt;pv&lt;/code&gt; disk space in order to store the &lt;code&gt;/znc-data&lt;/code&gt; configs.&lt;/li&gt;
&lt;li&gt;There is an &lt;code&gt;initContainers&lt;/code&gt; section that defines a container named &lt;code&gt;init-config&lt;/code&gt;, more about that below because it really ties everything together.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;znc&lt;/code&gt; container is straightforward, listening for connections on port &lt;code&gt;6667&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;What&amp;rsquo;s up with &lt;code&gt;init-config&lt;/code&gt;. Well, ZNC relies on you having a &lt;code&gt;znc.conf&lt;/code&gt; in place before the service starts. It also has a command line option &lt;code&gt;znc --makeconf&lt;/code&gt; that it expects you to run in order to interactively make that configuration file (and other important files). The &lt;code&gt;init-config&lt;/code&gt; container is running a loop checking that the &lt;code&gt;znc.conf&lt;/code&gt; file has been made and is in the persistent volume. The pod won&amp;rsquo;t complete it&amp;rsquo;s startup until &lt;code&gt;znc --makeconf&lt;/code&gt; has been run. If, on the other hand the file has already been made, the &lt;code&gt;init-config&lt;/code&gt; will be short lived.&lt;/p&gt;
&lt;p&gt;The first time you start this deployment you&amp;rsquo;ll see something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;[nackjicholson@vault ~]$ k get po
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME                           READY   STATUS     RESTARTS   AGE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;znc-bouncer-XXXXXXXXXX-YYYYY   0/1     Init:0/1   0          84s
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It is waiting for you to make the &lt;code&gt;znc.conf&lt;/code&gt;. So how do you do that? Get in the container and do it yourself!&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;[nackjicholson@vault ~]$ k exec -it znc-bouncer-XXXXXXXXXX-YYYYY -c init-config -- ./entrypoint.sh --makeconf
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[WARN  tini (64)] Tini is not running as PID 1 and isn&lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;t registered as a child subreaper.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;Zombie processes will not be re-parented to Tini, so zombie reaping won&amp;#39;&lt;/span&gt;t work.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;To fix the problem, use the -s option or set the environment variable TINI_SUBREAPER to register Tini as a child subreaper, or run Tini as PID 1.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ .. ] Checking &lt;span style=&#34;font-weight:bold&#34;&gt;for&lt;/span&gt; list of available modules...
&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;[ ** ] -- Global settings --
&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;[ ?? ] Listen on port (1025 to 65534): 6667
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ !! ] WARNING: Some web browsers reject ports 6667 and 6697. If you intend to
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ !! ] use ZNC&lt;span style=&#34;&#34;&gt;&amp;#39;&lt;/span&gt;s web interface, you might want to use another port.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ?? ] Proceed anyway? (yes/no) [yes]: yes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ?? ] Listen using SSL (yes/no) [no]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ?? ] Listen using both IPv4 and IPv6 (yes/no) [yes]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ .. ] Verifying the listener...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ** ] Unable to locate pem file: [/znc-data/znc.pem], creating it
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ .. ] Writing Pem file [/znc-data/znc.pem]...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ** ] Enabled global modules [webadmin]
&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;[ ** ] -- Admin user settings --
&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;[ ?? ] Username (alphanumeric): myuser
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ?? ] Enter password: MY_ZNC_PASSWORD
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ?? ] Confirm password: MY_ZNC_PASSWORD
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ?? ] Nick [myuser]: mynick
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ?? ] Alternate nick [mynick_]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ?? ] Ident [myuser]: mynick
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ?? ] Real name (optional): First Last
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ?? ] Bind host (optional):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ** ] Enabled user modules [chansaver, controlpanel]
&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;[ ?? ] Set up a network? (yes/no) [yes]:
&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;[ ** ] -- Network settings --
&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;[ ?? ] Name [freenode]: libera
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ?? ] Server host (host only): irc.libera.chat
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ?? ] Server uses SSL? (yes/no) [no]: yes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ?? ] Server port (1 to 65535) [6697]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ?? ] Server password (probably empty): MY_LIBERA_PASSWORD
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ?? ] Initial channels: &lt;span style=&#34;font-style:italic&#34;&gt;#systemcrafters&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ** ] Enabled network modules [simple_away]
&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;[ .. ] Writing config [/znc-data/configs/znc.conf]...
&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;[ ** ] To connect to this ZNC you need to connect to it as your IRC server
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ** ] using the port that you supplied.  You have to supply your login info
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ** ] as the IRC server password like this: user/network:pass.
&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;[ ** ] Try something like this in your IRC client...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ** ] /server &amp;lt;znc_server_ip&amp;gt; 6667 myuser:&amp;lt;pass&amp;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;[ ** ] To manage settings, users and networks, point your web browser to
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ ** ] http://&amp;lt;znc_server_ip&amp;gt;:6667/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As soon as that&amp;rsquo;s done, the &lt;code&gt;init-config&lt;/code&gt; containers original process sees the newly created &lt;code&gt;/znc-data/configs/znc.conf&lt;/code&gt; file and kills itself.&lt;/p&gt;
&lt;h3 id=&#34;znc-nodeport-service&#34;&gt;ZNC NodePort Service&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#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;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;: v1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;kind&lt;/span&gt;: Service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;labels&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;app&lt;/span&gt;: znc-bouncer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc-bouncer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;ports&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;font-weight:bold&#34;&gt;name&lt;/span&gt;: znc-app
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;port&lt;/span&gt;: 6667
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;protocol&lt;/span&gt;: TCP
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;targetPort&lt;/span&gt;: 6667
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;nodePort&lt;/span&gt;: 32667
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;selector&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;font-weight:bold&#34;&gt;app&lt;/span&gt;: znc-bouncer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold&#34;&gt;type&lt;/span&gt;: NodePort
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is pretty straightforward, runs a &lt;code&gt;NodePort&lt;/code&gt; service exposing port &lt;code&gt;32667&lt;/code&gt; and forwards it to our deployment listening on the &lt;code&gt;targetPort: 6667&lt;/code&gt;. From my diagram above this is what let&amp;rsquo;s us connect to the server using the &lt;code&gt;http://vault.local:32667&lt;/code&gt; URI.&lt;/p&gt;
&lt;p&gt;I fiddled around with using an Ingress to do this, but IRC clients typically ask for a host and port i.e. &lt;code&gt;znc.vault.local&lt;/code&gt; and I could not figure out how to get an Ingress and my local &lt;code&gt;mDNS&lt;/code&gt; to allow me to find the vault using a URL like &lt;code&gt;znc.vault.local&lt;/code&gt;. If you have found a better solution to this, please let me know, &lt;code&gt;/query nackjicholson&lt;/code&gt; on Libera.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I found a way to do this with Ingress, see &lt;a href=&#34;http://willvaughn.org/articles/irc-services-at-home-with-k3s&#34;&gt;IRC Services at Home with k3s&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;connecting-from-erc&#34;&gt;Connecting from ERC&lt;/h2&gt;
&lt;p&gt;My go-to IRC client is ERC within Emacs, you can probably apply the same idea to whatever client you use.&lt;/p&gt;
&lt;p&gt;One time:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(erc :server &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;vault.local&amp;#34;&lt;/span&gt; :port 32667 :nick &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;mynick&amp;#34;&lt;/span&gt; :password &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;myuser/libera:MY_ZNC_PASSWORD&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you&amp;rsquo;re going to load that in your &lt;code&gt;init.el&lt;/code&gt; you&amp;rsquo;d likely want something like this, and to leverage the &lt;code&gt;auth-source&lt;/code&gt; module in emacs to load your password securely.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;init.el&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(defun my--start-erc ()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (interactive)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-style:italic&#34;&gt;;; ZNC&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (erc :server &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;vault.local&amp;#34;&lt;/span&gt; :port 32667 :nick &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;mynick&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;.authinfo.gpg&lt;/em&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-netrc&#34; data-lang=&#34;netrc&#34;&gt;machine vault.local login mynick port 32667 password myuser/libera:MY_ZNC_PASSWORD
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I truly hope you&amp;rsquo;ll find that running your own ZNC on Kubernetes is a great learning experience, and works quite well! Be well, see you on irc.libera.chat!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>My Personal IRC Renaissance</title>
      <link>http://willvaughn.org/articles/my-personal-irc-renaissance/</link>
      <pubDate>Sat, 24 Jul 2021 19:29:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/my-personal-irc-renaissance/</guid>
      <description>&lt;h2 id=&#34;freenode-libera-plus-system-crafters&#34;&gt;Freenode-&amp;gt;Libera + System Crafters&lt;/h2&gt;
&lt;p&gt;A few months ago the parts of the Internet concerned with free and open source software and IT were abuzz about an &lt;a href=&#34;https://news.ycombinator.com/item?id=27286628&#34;&gt;IRC Exodus from Freenode to Libera&lt;/a&gt;. I hadn&amp;rsquo;t used IRC in quite a while, and had never been a regular user. I&amp;rsquo;ve always been interested in it but had never consistently logged in. Early this year I began to occassionaly come across videos from David Wilson&amp;rsquo;s &lt;a href=&#34;https://www.youtube.com/channel/UCAiiOTio8Yu69c3XnR7nQBQ&#34;&gt;System Crafters YouTube&lt;/a&gt; channel in my social channels. The videos were excellent, informative, organized, and well-aligned with my interest in GNU Emacs and Linux at large. I really got hooked by the playlist on &lt;a href=&#34;https://www.youtube.com/watch?v=RQK_DaaX34Q&amp;amp;list=PLEoMzSkcN8oPQtn7FQEF3D7sroZbXuPZ7&#34;&gt;Learning Emacs Lisp&lt;/a&gt;. Just after the Freenode/Libera kerfuffle, &lt;code&gt;daviwil&lt;/code&gt; (as I now know him) started the &lt;code&gt;#systemcrafters&lt;/code&gt; channel on &lt;a href=&#34;https://libera.chat&#34;&gt;Libera&lt;/a&gt; and did an &lt;a href=&#34;https://youtu.be/qWHTZIYTA4s&#34;&gt;excellent video&lt;/a&gt; and &lt;a href=&#34;https://youtu.be/Qci8t_jpVGA&#34;&gt;live stream&lt;/a&gt; detailing how to configure one of the built-in IRC clients in emacs &amp;ndash; &lt;a href=&#34;https://www.gnu.org/software/emacs/manual/html_mono/erc.html&#34;&gt;ERC&lt;/a&gt;. I followed along and for the first time had an IRC client I loved using! I also found a community in the &lt;code&gt;#systemcrafters&lt;/code&gt; channel that was welcoming, fun, helpful and collaborative.&lt;/p&gt;
&lt;p&gt;Below you&amp;rsquo;ll find descriptions of how far I am down the rabbit hole. I honestly don&amp;rsquo;t know how much further it goes! 😄&lt;/p&gt;
&lt;h2 id=&#34;znc&#34;&gt;ZNC&lt;/h2&gt;
&lt;p&gt;In the &lt;code&gt;#systemcrafters&lt;/code&gt; channel I learned that other folks were enhancing their IRC experience by using a &amp;ldquo;bouncer server&amp;rdquo; called &lt;a href=&#34;https://wiki.znc.in/ZNC&#34;&gt;ZNC&lt;/a&gt;. IRC is an old protocol with its origins in the beginning of the world wide web, if you&amp;rsquo;re not logged in you will just miss the messages that were sent to you. The way around this is to keep your client connected all the time, or to run a bouncer server that stays connected for you. The ZNC bouncer has many features that end up making IRC a little more useable. Essentially, you connect to the ZNC service and it replays what you missed in all your channels since your last login.&lt;/p&gt;
&lt;p&gt;I wanted to run my own ZNC. So, I dug in and figured out how to do it on my own Google Cloud instance running Centos 7. The culmination of that learning helped me write this addition to the System Crafter&amp;rsquo;s wiki: &lt;a href=&#34;https://wiki.systemcrafters.cc/community/znc-bouncer-servers/&#34;&gt;ZNC Bouncer Servers Setup&lt;/a&gt;. The only downside is that I was running a publicly exposed server on the internet and spending about $40/mo to keep it going. There are other more affordable hosting options of course, but I&amp;rsquo;ve decided to run it on a Mini-PC on my home network. There will be a blog coming soon on that! 🖥&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: Check out the new blogs &lt;a href=&#34;http://willvaughn.org/articles/running-znc-bouncer-with-k3s&#34;&gt;Running ZNC Bouncer with K3s&lt;/a&gt; and &lt;a href=&#34;http://willvaughn.org/articles/irc-services-at-home-with-k3s/&#34;&gt;IRC Services at Home with K3s&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;0x0-dot-st&#34;&gt;0x0.st&lt;/h2&gt;
&lt;p&gt;IRC is old, have I said that yet? Charmingly old mind you! To send files, images, or even some copy/pasta code users typically use file-sharing or pastebin services. One such service is &lt;a href=&#34;https://0x0.st&#34;&gt;https://0x0.st&lt;/a&gt;. And here&amp;rsquo;s how to use it from the command line.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;
HTTP POST files here:
    curl -F&amp;#39;file=@yourfile.png&amp;#39; https://0x0.st
You can also POST remote URLs:
    curl -F&amp;#39;url=http://example.com/image.jpg&amp;#39; https://0x0.st
Or you can shorten URLs:
    curl -F&amp;#39;shorten=http://example.com/some/long/url&amp;#39; https://0x0.st
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After doing this two or three times, and having watched 7 videos about learning emacs lisp I decided I could write an emacs package to make this more convenient. I found that a package on sourcehut already existed &lt;a href=&#34;https://git.sr.ht/~pkal/nullpointer-emacs&#34;&gt;~pkal/nullpointer-emacs&lt;/a&gt;. Because my goal was really to learn Elisp, I read this package more than I used it. In doing so I found that I could fix a few bugs, refactor it for better testability, and add a few features to it. I reached out to &lt;code&gt;pkal&lt;/code&gt; on Libera (yes!) and told him that I had made a fork. After some discussion we decided I should be the maintainer of the 0x0 namespace on MELPA. We transferred the project over to me. I&amp;rsquo;m officially an emacs lisp programmer! 🤓&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/willvaughn/emacs-0x0&#34;&gt;willvaughn/emacs-0x0&lt;/a&gt; on GitLab&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://melpa.org/#/0x0&#34;&gt;0x0&lt;/a&gt; on MELPA&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;bitlbee-and-signald&#34;&gt;Bitlbee &amp;amp; Signald&lt;/h2&gt;
&lt;p&gt;So, now I&amp;rsquo;m in ERC and IRC all the time. This is basically my facebook or instagram. It&amp;rsquo;s inevitable that I should start thinking about how I can ERC-ify all textual communication in my life. I use Emacs for email, RSS, youtube, reddit, and news. Why shouldn&amp;rsquo;t I use it for texting my friends and family? That&amp;rsquo;s what &lt;a href=&#34;https://www.bitlbee.org/main.php/news.r.html&#34;&gt;Bitlbee&lt;/a&gt; is for, it bridges IRC to other common chat applications. I&amp;rsquo;m now running my own bitlbee server on my local network too! Some nice folks wrote and distributed &lt;a href=&#34;https://github.com/hoehermann/libpurple-signald&#34;&gt;libpurple-signald&lt;/a&gt;, a library that bridges the &lt;a href=&#34;https://www.signal.org/&#34;&gt;Signal&lt;/a&gt; chat application to bitlbee, allowing me to text my wife and my friends from the lovely confines of emacs. 🗨&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: Check out the new blogs &lt;a href=&#34;http://willvaughn.org/articles/running-bitlbee-and-signald-with-docker/&#34;&gt;Running Bitlbee &amp;amp; Signald with Docker&lt;/a&gt; and &lt;a href=&#34;http://willvaughn.org/articles/irc-services-at-home-with-k3s/&#34;&gt;IRC Services at Home with K3s&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;crafter-bot&#34;&gt;crafter-bot&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m lurking on this project &lt;a href=&#34;https://github.com/benoitj/crafter-bot&#34;&gt;benoitj/crafter-bot&lt;/a&gt;, the friendly &lt;code&gt;#systemcrafters&lt;/code&gt; IRC bot written in &amp;ndash; you guessed it &amp;ndash; Emacs Lisp! I haven&amp;rsquo;t contributed but I think &lt;a href=&#34;https://blog.benoitj.ca/&#34;&gt;benoitj&lt;/a&gt; is up to some interesting things and I&amp;rsquo;m keeping tabs on it. 🤖&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Thanks for reading about my IRC revival. Come find me on the &lt;code&gt;#systemcrafters&lt;/code&gt; channel on irc.libera.chat. You can &lt;code&gt;/query nackjicholson&lt;/code&gt; anytime! Hope to hear from you soon! 🖖&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The git-add manual review</title>
      <link>http://willvaughn.org/articles/the-git-add-manual-review/</link>
      <pubDate>Sun, 27 Dec 2020 23:26:00 -0800</pubDate>
      
      <guid>http://willvaughn.org/articles/the-git-add-manual-review/</guid>
      <description>&lt;p&gt;The &lt;code&gt;git-add&lt;/code&gt; command is easy to overlook, I&amp;rsquo;ve used it thousands of times without ever thinking about reading the manual. I was excited to find out what what was in here, because I use this command so much that any learnings will probably payoff quickly. From using magit in emacs I knew it was possible to surgically add lines and blocks of code into the commit index, but using the CLI I&amp;rsquo;ve never bothered to try. I typically only add full files.&lt;/p&gt;
&lt;h2 id=&#34;basics&#34;&gt;Basics&lt;/h2&gt;
&lt;p&gt;This command exists to prepare the content of the &amp;ldquo;index&amp;rdquo; to be used for the next commit.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;git add ./path/to/file.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git add .
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git add --all
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These are the ways I typically use this command, and they&amp;rsquo;re perfectly valid! This is about all you need to know in order to take your working tree changes and prepare them for a commit. If you need more control you can get into using wildcards:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;git add docs/&lt;span style=&#34;font-weight:bold;font-style:italic&#34;&gt;\*&lt;/span&gt;.txt
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;pick-and-choose-with-edit&#34;&gt;Pick and Choose with &lt;code&gt;--edit&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Use this with some caution, but this option on git add will let you change the diff directly to be what you want to apply to the index. It will show you the &lt;code&gt;+&lt;/code&gt; and &lt;code&gt;-&lt;/code&gt; signs at the front of lines and you can delete the signs or completely remove the lines. When you save the edit, the things you kept will be added to the index and the things you left behind will still be in the working tree.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a diff with two simple chunks where I added and deleted some lines from a README. With the &lt;code&gt;--edit&lt;/code&gt; option I&amp;rsquo;d like to only commit part of these. With the verbosity of git diffs even this small example can be a lot to read, you should go edit some files and try it yourself to get a feel.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;diff --git a/README.md b/README.md
index eb107d0..fa359f8 100644
--- a/README.md
+++ b/README.md
@@ -52,10 +52,6 @@ https://stackoverflow.com/questions/44527452/cant-open-lib-odbc-driver-13-for-sq

 #### Installing MySQL

-##### macOS
-
-TODO: Probably something like `brew install mysql` or `brew install mariadb`.
-
 ##### amzn2

 ```bash
@@ -63,6 +59,13 @@ sudo yum install -y https://dev.mysql.com/get/mysql57-community-release-el7-11.n
 sudo yum install -y mysql-community-client
 ```

+How about add some more description here.
+Oh but this is toooooo much info, so let&amp;#39;s take it out
+blah
+blah
+
+I want to leave this important bit in though!
+
 ### Installing Project Dependencies

 ```
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So I&amp;rsquo;ll edit that:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;git add --edit
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This opens up my &lt;code&gt;$EDITOR&lt;/code&gt; (vim) and then I can tweak this diff. Here&amp;rsquo;s my edit that leaves the &lt;code&gt;macOS&lt;/code&gt; header in the first diff chunk and important bits of the second chunk.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;diff --git a/README.md b/README.md
index eb107d0..fa359f8 100644
--- a/README.md
+++ b/README.md
@@ -48,25 +48,28 @@ brew tap microsoft/mssql-release https://github.com/Microsoft/homebrew-mssql-rel
 brew update
 brew install msodbcsql mssql-tools
 ```
 https://stackoverflow.com/questions/44527452/cant-open-lib-odbc-driver-13-for-sql-server-sym-linking-issue

 #### Installing MySQL

##### macOS
-
-TODO: Probably something like `brew install mysql` or `brew install mariadb`.
-
 ##### amzn2

 ```bash
 sudo yum install -y https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm
 sudo yum install -y mysql-community-client
 ```

+How about add some more description here.
+
+I want to leave this important bit in though!
+
 ### Installing Project Dependencies

 ```
 poetry install
 ```

 If you get a clang/ssl error during `poetry install`, it&amp;#39;s possible your linker+brew+Apple aren&amp;#39;t playing well together. Try pointing your linker to openssl directly, via:
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;interactive-additions-with-p-patch&#34;&gt;Interactive additions with &lt;code&gt;-p&lt;/code&gt;, &lt;code&gt;--patch&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Using the &lt;code&gt;--interactive&lt;/code&gt; flag you get an interactive mode for exploring the state of your repo and what to add. The useful bit of this to me was the &lt;code&gt;patch&lt;/code&gt; subcommand, and you can go to interactive patch mode directly using the &lt;code&gt;--patch&lt;/code&gt; option instead of &lt;code&gt;--interactive&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In patch mode you are presented with hunks of your diff and a prompt to decide what to do with each hunk. Here are the possible decisions:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;prompt&lt;/th&gt;
          &lt;th&gt;description&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;y&lt;/td&gt;
          &lt;td&gt;stage this hunk&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;n&lt;/td&gt;
          &lt;td&gt;do not stage this hunk&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;q&lt;/td&gt;
          &lt;td&gt;quit; do not stage this or any remaining&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;a&lt;/td&gt;
          &lt;td&gt;stage this hunk and all remaining&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;d&lt;/td&gt;
          &lt;td&gt;do not stage this hunk or any remaining&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;g&lt;/td&gt;
          &lt;td&gt;select a hunk to go  to&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;\/&lt;/td&gt;
          &lt;td&gt;search for a hunk matching regex&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;j&lt;/td&gt;
          &lt;td&gt;leave this hunk undecided, see next undecided&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;J&lt;/td&gt;
          &lt;td&gt;leave this hunk undecided, see next&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;k&lt;/td&gt;
          &lt;td&gt;leave this hunk undecided, see previous undecided&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;K&lt;/td&gt;
          &lt;td&gt;leave this hunk undecided, see previous&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;s&lt;/td&gt;
          &lt;td&gt;split the current hunk into smaller hunks&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;e&lt;/td&gt;
          &lt;td&gt;manually edit the current hunk&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Pretty easy, answer the prompts and make your decisions. When you&amp;rsquo;re done the index will be updated with the hunks you selected. The ones you didn&amp;rsquo;t select are still unstaged.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been actively trying to make cleaner and smaller commits to simplify code review for my colleagues. I&amp;rsquo;m hopeful that what I learned here with &lt;code&gt;git-add&lt;/code&gt; will help the next time I&amp;rsquo;m faced with a messy or complicated diff that could be split into simpler pieces. Thanks for reading!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Arch Linux on my Toshiba Chromebook 2 (2014)</title>
      <link>http://willvaughn.org/articles/arch-linux-on-my-toshiba-chromebook-2--2014/</link>
      <pubDate>Tue, 15 Sep 2020 08:20:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/arch-linux-on-my-toshiba-chromebook-2--2014/</guid>
      <description>&lt;p&gt;I started by trying to install Fedora 32 on this machine, just could not figure it out. I don&amp;rsquo;t know if Fedora 32 Workstation is intended for use on this madly resource constrained little machine. So, the minimal nature of Arch Linux lends itself to having a chance of working!&lt;/p&gt;
&lt;h2 id=&#34;specs-of-the-laptop&#34;&gt;Specs of the laptop&lt;/h2&gt;
&lt;p&gt;By looking at the &lt;a href=&#34;https://wiki.archlinux.org/index.php/Chrome_OS_devices/Chromebook&#34;&gt;Chrome OS Devices Arch Wiki&lt;/a&gt; I found some basic specs for the Toshiba Chromebook 2&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Available&lt;/th&gt;
          &lt;th&gt;Brand&lt;/th&gt;
          &lt;th&gt;Model&lt;/th&gt;
          &lt;th&gt;Processor&lt;/th&gt;
          &lt;th&gt;RAM&lt;/th&gt;
          &lt;th&gt;Storage&lt;/th&gt;
          &lt;th&gt;Upgradable&lt;/th&gt;
          &lt;th&gt;SeaBIOS&lt;/th&gt;
          &lt;th&gt;Remarks&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Jan 2014&lt;/td&gt;
          &lt;td&gt;Toshiba&lt;/td&gt;
          &lt;td&gt;CB30/CB35 Chromebook&lt;/td&gt;
          &lt;td&gt;1.4 GHz Intel Celeron 2955U&lt;/td&gt;
          &lt;td&gt;2GB DDR3&lt;/td&gt;
          &lt;td&gt;16GB eMMC&lt;/td&gt;
          &lt;td&gt;No&lt;/td&gt;
          &lt;td&gt;Yes&lt;/td&gt;
          &lt;td&gt;Custom firmware available&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;prepping-the-chromebook-to-be-hacked-on&#34;&gt;Prepping the Chromebook to be hacked on&lt;/h2&gt;
&lt;p&gt;This was fun. These resources helped me get it done. I flailed for a while and had to read these pages a lot in order to figure it out.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://wiki.archlinux.org/index.php/Chrome_OS_devices#Enabling_Legacy_Boot_Mode&#34;&gt;https://wiki.archlinux.org/index.php/Chrome_OS_devices#Enabling_Legacy_Boot_Mode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://linuxconfig.org/how-to-install-any-linux-distro-on-a-chromebook#h2-getting-the-chromebook-ready&#34;&gt;https://linuxconfig.org/how-to-install-any-linux-distro-on-a-chromebook#h2-getting-the-chromebook-ready&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=JcZ711cxKdA&#34;&gt;https://www.youtube.com/watch?v=JcZ711cxKdA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://wiki.archlinux.org/index.php/Chrome_OS_devices/Custom_firmware#Flashing_with_MrChromebox&#39;s_Firmware_Utility_Script&#34;&gt;https://wiki.archlinux.org/index.php/Chrome_OS_devices/Custom_firmware#Flashing_with_MrChromebox&#39;s_Firmware_Utility_Script&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://mrchromebox.tech/&#34;&gt;https://mrchromebox.tech/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;installation-process&#34;&gt;Installation process&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://wiki.archlinux.org/index.php/Installation_guide&#34;&gt;https://wiki.archlinux.org/index.php/Installation_guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;partitioning&#34;&gt;Partitioning&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://wiki.archlinux.org/index.php/Partitioning#Example_layouts&#34;&gt;Arch Wiki Partitioning&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://wiki.archlinux.org/index.php/Swap#Swap_file&#34;&gt;Arch Wiki Swap file&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I used &lt;a href=&#34;https://wiki.archlinux.org/index.php/Parted&#34;&gt;&lt;code&gt;parted&lt;/code&gt;&lt;/a&gt; to partition the disk. First I figured out which device was the correct one to partition by running&amp;hellip;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;lsblk -p
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For me this was &lt;code&gt;/dev/mmcblk0&lt;/code&gt; with 14.7G of space. We&amp;rsquo;re working with a tiny SSD drive and that makes hard-drive space important. To simplify setup and because of the constrained disk space I decided to go with the required &lt;code&gt;boot&lt;/code&gt; partition for UEFI and a single &lt;code&gt;/&lt;/code&gt; root partition. For swap space, using a &lt;code&gt;1GB&lt;/code&gt; swapfile instead of a dedicated partition.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;parted /dev/mmcblk0
(parted) mklabel gpt
(parted) mkpart &amp;#34;EFI boot partition&amp;#34; fat32 1MiB 261MiB
(parted) set 1 esp on
(parted) mkpart &amp;#34;root partition&amp;#34; ext4 261MiB 100%
(parted) quit
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Formatting the partitions.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;mkfs.vfat -F32 -n EFI /dev/mmcblk0p1
mkfs.ext4 /dev/mmcblk0p2
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;mounting-the-new-filesystem&#34;&gt;Mounting the new filesystem&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;mount /dev/mmcblk0p2 /mnt
mkdir /mnt/boot
mount /dev/mmcblk0p1 /mnt/boot
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;mirror-list&#34;&gt;Mirror List&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;pacman -Sy reflector
reflector -c &amp;#39;United States&amp;#39; -f 12 -l 12 --verbose --save /etc/pacman.d/mirrorlist
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This didn&amp;rsquo;t work, so I just munged it locally. I&amp;rsquo;ll run it again after install.&lt;/p&gt;
&lt;h3 id=&#34;pacstrap&#34;&gt;Pacstrap&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;pacstrap base base-devel linux linux-firmware intel-ucode sudo vim emacs git networkmanager
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;the-rest&#34;&gt;The Rest&lt;/h3&gt;
&lt;p&gt;Follow the &lt;a href=&#34;https://wiki.archlinux.org/index.php/Installation_Guide&#34;&gt;Arch Wiki Installation guide&lt;/a&gt;, and clicked on many links to read more. I used GRUB as a boot loader.&lt;/p&gt;
&lt;h2 id=&#34;post-install&#34;&gt;Post Install&lt;/h2&gt;
&lt;h3 id=&#34;swap-file&#34;&gt;Swap file&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://wiki.archlinux.org/index.php/Swap#Swap_file&#34;&gt;Arch Wiki - Swap File&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I decided to use a 1GB swap file for swap space at &lt;code&gt;/swapfile&lt;/code&gt;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;# dd if=/dev/zero of=/swapfile bs=1M count=1024 status=progress
# chmod 600 /swapfile
# mkswap /swapfile
# swapon /swapfile
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And update &lt;strong&gt;etc/fstab&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;/swapfile none swap defaults 0 0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Use &lt;code&gt;free -m&lt;/code&gt; to verify that the swap is available.&lt;/p&gt;
&lt;h3 id=&#34;manual-pages&#34;&gt;Manual pages&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;# pacman -S man-db man-pages
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I just took apart a laptop, installed a new bios on it, and installed Arch Linux for the third or fourth time. Each time I get more comfortable with what a computer actually is every time I do this. I now have GNOME, firefox and Emacs installed on this little thing and I am actually using it around the house for basic end user style computing, and it works really well. Email me if you have one of these relics and want some help doing the same.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Installing CentOS on Protectli Vault</title>
      <link>http://willvaughn.org/articles/installing-centos-on-protectli-vault/</link>
      <pubDate>Wed, 05 Aug 2020 08:15:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/installing-centos-on-protectli-vault/</guid>
      <description>&lt;p&gt;I am installing CentOS over the top of ubuntu on my Protectli 4-port Vault Mini PC.&lt;/p&gt;
&lt;h2 id=&#34;downloading&#34;&gt;Downloading&lt;/h2&gt;
&lt;p&gt;I downloaded a &amp;ldquo;minimal&amp;rdquo; ISO of centos from the &lt;a href=&#34;https://www.centos.org/download/&#34;&gt;CentOS Download&lt;/a&gt; page. The CentOS Wiki has these &lt;a href=&#34;https://wiki.centos.org/HowTos/InstallFromUSBkey&#34;&gt;instructions&lt;/a&gt; that show I can copy this to my usb key with &lt;code&gt;dd&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So, where is my USB key mounted?&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;lsblk -p
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Mine is &lt;code&gt;/dev/sdb&lt;/code&gt;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;sudo dd if=/home/nackjicholson/Downloads/CentOS-8.2.2004-x86_64-minimal.iso of=/dev/sdb
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That takes a while, then you can &lt;code&gt;eject&lt;/code&gt; it&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;sudo eject /dev/sdb
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Shut down my vault, put the USB key in and follow the &lt;a href=&#34;https://protectli.com/kb/how-to-install-centos-on-the-vault/&#34;&gt;Protectli CentOS Install Docs&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Pi-hole, WireGuard, DNS-Over-HTTPS with a Raspberry Pi 3</title>
      <link>http://willvaughn.org/articles/pihole-and-wireguard-vpn-on-raspberry-pi-3/</link>
      <pubDate>Wed, 05 Aug 2020 08:12:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/pihole-and-wireguard-vpn-on-raspberry-pi-3/</guid>
      <description>&lt;h2 id=&#34;why&#34;&gt;Why?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;RPI 3: Sitting around collecting dust.&lt;/li&gt;
&lt;li&gt;Pi-hole: I hate ads, this is an amazing tool that blocks ads for all devices connected to a network.&lt;/li&gt;
&lt;li&gt;DNS-Over-HTTPS: Fewer people having access to my internet usage information.&lt;/li&gt;
&lt;li&gt;WireGuard: Secure remote access to my homelab, and with Pi-hole ad-blocking from my mobile phone.&lt;/li&gt;
&lt;li&gt;Learning!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I am doing all of this to learn networking and linux administration. So, when I can choose the easy way or the hard way, I take the hard way. If you&amp;rsquo;re looking for the fastest way to setup a VPN and Pi-hole, you may want to consult another guide. This article is mostly for myself to have documentation of all the decisions I&amp;rsquo;m making at home. I will present the resources I consult alongside key artifacts and descriptions of where I varied my setup from the references.&lt;/p&gt;
&lt;h2 id=&#34;router-specifics&#34;&gt;Router specifics&lt;/h2&gt;
&lt;p&gt;A lot of what I did was enabled by my router, a capable tool called the &lt;a href=&#34;https://www.ui.com/edgemax/edgerouter-x/&#34;&gt;EdgeRouterX&lt;/a&gt;. When relevant I&amp;rsquo;ll show the Firewall, NAT and DNS settings I used. You&amp;rsquo;re probably running something else, you may be able to do what I did with your router, or maybe not. I&amp;rsquo;ll leave it to you research how to make similar changes on your router or firewall.&lt;/p&gt;
&lt;h2 id=&#34;conceptual-diagram&#34;&gt;Conceptual Diagram&lt;/h2&gt;
&lt;p&gt;Accessing my home network when I&amp;rsquo;m away, and getting the benefit of ad-blocking while I&amp;rsquo;m connected over the VPN.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;http://willvaughn.org/images/rpi3-wireguard/rpi3-wireguard-concept.png&#34;&gt;
&lt;/figure&gt;

&lt;h2 id=&#34;ssh-access-for-the-rpi-3&#34;&gt;SSH Access for the RPI 3&lt;/h2&gt;
&lt;p&gt;This is an optional step, you can plug a monitor into your RPI 3 if you want. I prefer to use my normal workstation and ssh into the RPI 3 to work on it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.raspberrypi.org/documentation/remote-access/ssh/&#34;&gt;RPI Docs - SSH&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.raspberrypi.org/documentation/remote-access/ssh/passwordless.md&#34;&gt;RPI Docs - Passwordless SSH&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When complete you should be able to SSH into the pi.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;ssh pi@&amp;lt;your-pi-IP&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;running-pi-hole&#34;&gt;Running Pi-hole&lt;/h2&gt;
&lt;p&gt;The Pi-hole is a DNS server that you can use on your network to filter out ads before they every get to your browser page. This section details getting a Pi-hole up and running.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.pi-hole.net/&#34;&gt;Pi-hole Docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.pi-hole.net/main/prerequisites/&#34;&gt;Pi-hole Docs - Prerequisites&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For firewall settings I blindly ran these commands after reading a little bit in the docs about what they do.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;iptables -I INPUT 1 -s 192.168.0.0/16 -p tcp -m tcp --dport 80 -j ACCEPT
iptables -I INPUT 1 -s 127.0.0.0/8 -p tcp -m tcp --dport 53 -j ACCEPT
iptables -I INPUT 1 -s 127.0.0.0/8 -p udp -m udp --dport 53 -j ACCEPT
iptables -I INPUT 1 -s 192.168.0.0/16 -p tcp -m tcp --dport 53 -j ACCEPT
iptables -I INPUT 1 -s 192.168.0.0/16 -p udp -m udp --dport 53 -j ACCEPT
iptables -I INPUT 1 -p udp --dport 67:68 --sport 67:68 -j ACCEPT
iptables -I INPUT 1 -p tcp -m tcp --dport 4711:4720 -i lo -j ACCEPT
iptables -I INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

ip6tables -I INPUT -p udp -m udp --sport 546:547 --dport 546:547 -j ACCEPT
ip6tables -I INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;installing&#34;&gt;Installing&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.raspberrypi.org/documentation/configuration/tcpip/README.md&#34;&gt;RPI Docs - TCP/IP Static IP address&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.pi-hole.net/main/basic-install/&#34;&gt;Pi-hole Docs - Install&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pi-hole has TUI application to aid installation.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;curl -sSL https://install.pi-hole.net | bash
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;My answers to the questions the TUI asks:&lt;/p&gt;
&lt;p&gt;Note that throughout this article &lt;code&gt;192.168.1.1&lt;/code&gt; is my router gateway, and &lt;code&gt;192.168.1.63&lt;/code&gt; is the IP of my RPI 3.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Select Upstream DNS Provider. To use your own, select Custom.&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;Cloudflare&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Pi-hole relies on third party lists in order to block ads.&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; &lt;a href=&#34;https://github.com/StevenBlack/hosts&#34;&gt;StevenBlack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; MalwareDom&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Select Protocols (press space to toggle selection)&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; IPv4&lt;/li&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; IPv6&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Do you want to use your current network settings as a static address?&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;IP address: 192.168.1.63/24&lt;/li&gt;
&lt;li&gt;Gateway: 192.168.1.1&lt;/li&gt;
&lt;li&gt;Yes&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Do you wish to install the web admin interface?&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; On&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Do you wish to install the web server (lighttpd)?&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; On&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Do you want to log queries?&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; On&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Select a privacy mode for FTL.&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 0 Show Everything&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After install be sure to copy your admin webpage login. I also checked the lines added to &lt;code&gt;/etc/dhcpcd.conf&lt;/code&gt; (as referenced in the &lt;a href=&#34;https://docs.pi-hole.net/main/prerequisites/#ip-addressing&#34;&gt;prerequisites&lt;/a&gt;). I didn&amp;rsquo;t actually find that Pi-hole had added any lines, so I configured &lt;code&gt;dhcpcd.conf&lt;/code&gt; myself to statically set an IP for the RPI 3 on my network.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cfg&#34; data-lang=&#34;cfg&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;# Static IP configuration:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;# Using my EdgeRouterX 192.168.1.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;font-style:italic&#34;&gt;# Pointing the nameserver locally and backed up with Cloudflare&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;interface eth0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;static ip_address=&lt;span style=&#34;font-style:italic&#34;&gt;192.168.1.63/24&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;static routers=&lt;span style=&#34;font-style:italic&#34;&gt;192.168.1.1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;static domain_name_servers=&lt;span style=&#34;font-style:italic&#34;&gt;127.0.0.1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In EdgeRouterX I configured the LAN settings to have a reserved IP (Static MAC/IP Mapping) for the RPI 3.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Name&lt;/th&gt;
          &lt;th&gt;MAC Address&lt;/th&gt;
          &lt;th&gt;IP Address&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;rpi3&lt;/td&gt;
          &lt;td&gt;xx:xx:xx:xx&lt;/td&gt;
          &lt;td&gt;192.168.1.63&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;use-pi-hole-for-dns-with-edgerouterx&#34;&gt;Use Pi-hole for DNS with EdgeRouterX&lt;/h3&gt;
&lt;p&gt;With this configuration every device in the network uses the Pi-hole server to resolve DNS names.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;http://willvaughn.org/images/rpi3-wireguard/edgerouterx-dns-to-rpi3.png&#34;&gt;
&lt;/figure&gt;

&lt;h3 id=&#34;whitelist-management-script&#34;&gt;Whitelist management script&lt;/h3&gt;
&lt;p&gt;This section details setting up a script to update the Pi-hole with commonly whitelisted domains. With this setup I rarely find that I need to whitelist random things that shouldn&amp;rsquo;t be blocked by the Pi-hole.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/anudeepND/whitelist&#34;&gt;anudeepND whitelist&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;!--listend--&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;git clone https://github.com/anudeepND/whitelist.git
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I setup a cron job with &lt;code&gt;crontab -e&lt;/code&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;@weekly sudo /home/pi/whitelist/scripts/whitelist.sh
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;dns-over-https&#34;&gt;DNS Over HTTPS&lt;/h3&gt;
&lt;p&gt;Doing DNS over HTTPS adds another level of privacy, but it&amp;rsquo;s definitely optional. I chose to do this for my own learning.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.pi-hole.net/guides/dns-over-https/&#34;&gt;Pi-hole Docs - DNS over HTTPS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Most, if not all, of this is in those docs. I&amp;rsquo;m just putting it here for documenting files I made on the RPI 3.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;wget https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-arm.tgz
tar -xvzf cloudflared-stable-linux-arm.tgz
sudo cp ./cloudflared /usr/local/bin
sudo chmod +x /usr/local/bin/cloudflared
cloudflared -v
rm ./cloudflared
rm ./cloudflared-stable-linux-arm.tgz
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Configuring &lt;code&gt;cloudflared&lt;/code&gt; to run on startup&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;sudo useradd -s /usr/sbin/nologin -r -M cloudflared
sudo vim /etc/default/cloudflared
&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cfg&#34; data-lang=&#34;cfg&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;# Commandline args for cloudflared&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;CLOUDFLARED_OPTS=&lt;span style=&#34;font-style:italic&#34;&gt;--port 5053 --upstream https://1.1.1.1/dns-query --upstream https://1.0.0.1/dns-query&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;sudo chown cloudflared:cloudflared /etc/default/cloudflared
sudo chown cloudflared:cloudflared /usr/local/bin/cloudflared
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;sudo vim /etc/systemd/system/cloudflared.service
&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cfg&#34; data-lang=&#34;cfg&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;[Unit]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Description=&lt;span style=&#34;font-style:italic&#34;&gt;cloudflared DNS over HTTPS proxy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;After=&lt;span style=&#34;font-style:italic&#34;&gt;syslog.target network-online.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;font-weight:bold&#34;&gt;[Service]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Type=&lt;span style=&#34;font-style:italic&#34;&gt;simple&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User=&lt;span style=&#34;font-style:italic&#34;&gt;cloudflared&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EnvironmentFile=&lt;span style=&#34;font-style:italic&#34;&gt;/etc/default/cloudflared&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ExecStart=&lt;span style=&#34;font-style:italic&#34;&gt;/usr/local/bin/cloudflared proxy-dns $CLOUDFLARED_OPTS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Restart=&lt;span style=&#34;font-style:italic&#34;&gt;on-failure&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;RestartSec=&lt;span style=&#34;font-style:italic&#34;&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;KillMode=&lt;span style=&#34;font-style:italic&#34;&gt;process&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;font-weight:bold&#34;&gt;[Install]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;WantedBy=&lt;span style=&#34;font-style:italic&#34;&gt;multi-user.target&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;sudo systemctl enable cloudflared
sudo systemctl start cloudflared
sudo systemctl status cloudflared
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Test it:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;dig @127.0.0.1 -p 5053 google.com
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And configure the Pi-hole to use it as its Custom IPv4 Upstream DNS &lt;code&gt;127.0.0.1#5053&lt;/code&gt;. Below are my complete Pi-hole DNS settings.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;http://willvaughn.org/images/rpi3-wireguard/pi-hole-dns-settings.png&#34;&gt;
&lt;/figure&gt;

&lt;h2 id=&#34;exposing-our-rpi-3-to-the-internet-with-ddns-dot&#34;&gt;Exposing our RPI 3 to the internet with DDNS.&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://engineerworkshop.com/blog/connecting-your-raspberry-pi-web-server-to-the-internet/&#34;&gt;EngineerWorkshop - Connection your Raspberry Pi Webserver to the Internet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://medium.com/lumberstack/how-to-setup-namecheap-dynamic-dns-on-edgerouter-x-gui-c81a6974f604&#34;&gt;Namecheap DDNS with EdgeRouterX&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Engineer Workshop blog describes using &lt;code&gt;ddclient&lt;/code&gt; to set up a dynamic DNS client to inform the DNS nameservers of the world automatically whenever our dynamic IP is changed by the ISP. My EdgeRouterX can do this instead, so I opted to go that route. I use Namecheap as my registrar so there are some screens here of it&amp;rsquo;s administration UI.&lt;/p&gt;
&lt;h3 id=&#34;namecheap-and-edgerouterx-ddns-setup&#34;&gt;Namecheap and EdgeRouterX DDNS setup&lt;/h3&gt;
&lt;p&gt;All of the Namecheap settings you need to change will be under the &lt;em&gt;Advanced DNS&lt;/em&gt; on the management page for your domain. I setup DynamicDNS in my Namecheap domain management interface. There is a simple toggle to enable it and you get back a password. What DynamicDNS does is allow a DNS client to update the IP where the domain name &lt;code&gt;mydomain.com&lt;/code&gt; resolves to. My EdgeRouterX has &lt;code&gt;ddclient&lt;/code&gt; installed on it and has a configuration screen for it. The router can detect when my ISP has changed my Public IP and it will automatically update my domain name with the new IP.&lt;/p&gt;
&lt;p&gt;To this end I setup an &lt;code&gt;A+ Dynamic DNS Record&lt;/code&gt; for my top level domain, using &lt;code&gt;127.0.0.1&lt;/code&gt; as a default value to begin with. If we setup our EdgeRouterX/ddclient correctly we should see this get updated with the real PublicIP of our home network.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Type&lt;/th&gt;
          &lt;th&gt;Host&lt;/th&gt;
          &lt;th&gt;Value&lt;/th&gt;
          &lt;th&gt;TTL&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;A+&lt;/td&gt;
          &lt;td&gt;@&lt;/td&gt;
          &lt;td&gt;127.0.0.1&lt;/td&gt;
          &lt;td&gt;Automatic&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Here is the EdgeRouterX configuration:&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;http://willvaughn.org/images/rpi3-wireguard/edgerouterx-namecheap-ddns-client.png&#34;&gt;
&lt;/figure&gt;

&lt;p&gt;The &lt;code&gt;URL&lt;/code&gt; field there is &lt;code&gt;dynamicdns.park-your-domain.com/getip&lt;/code&gt;. And the &lt;code&gt;Server&lt;/code&gt; is &lt;code&gt;dynamicdns.park-your-domain.com&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&#34;edgerouterx-port-forwarding&#34;&gt;EdgeRouterX Port Forwarding&lt;/h3&gt;
&lt;p&gt;The last step in exposing our server to the internet is to punch a hole in our firewall that allows traffic to our domain name to be forwarded to port &lt;code&gt;51820&lt;/code&gt; on our RPI 3 where the WireGuard VPN will be running.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&#34;http://willvaughn.org/images/rpi3-wireguard/edgerouterx-vpn-port-forward.png&#34;&gt;
&lt;/figure&gt;

&lt;p&gt;You won&amp;rsquo;t know if this is fully working until after you get through setting up WireGuard. You can verify what you have by instead opening up port 80 breifly and seeing that you can reach the Pi-hole webapp. &lt;strong&gt;&lt;strong&gt;BE SURE TO CHANGE IT BACK&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;running-wireguard&#34;&gt;Running WireGuard&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.wireguard.com/&#34;&gt;WireGuard&lt;/a&gt; is a new-ish VPN technology that attempts to be simple and secure.&lt;/p&gt;
&lt;h3 id=&#34;installing&#34;&gt;Installing&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/adrianmihalko/raspberrypiwireguard&#34;&gt;adrianmihalko/raspberrypiwireguard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://engineerworkshop.com/blog/how-to-set-up-wireguard-on-a-raspberry-pi/&#34;&gt;Engineer Workshop - How to set up WireGuard on a Raspberry Pi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I followed the instructions on this github page . They were also referenced in this ]] which I also followed. It is fairly involved because &lt;code&gt;wireguard&lt;/code&gt; isn&amp;rsquo;t in the main raspian distro. I chose to follow a mix of these instructions, but ended up writing my keys to a restricted location using &lt;code&gt;umask 077&lt;/code&gt; for a little extra security. I also chose to make my &lt;code&gt;wg0&lt;/code&gt; interface IPs be in the range &lt;code&gt;192.168.2.0/24&lt;/code&gt;. My RPI 3 WireGuard Server is &lt;code&gt;192.168.2.1&lt;/code&gt; and it&amp;rsquo;s peer (the client) is &lt;code&gt;192.168.2.2&lt;/code&gt;. I also used the &lt;code&gt;wg-quick@wg0.service&lt;/code&gt; systemd unit to run the server.&lt;/p&gt;
&lt;p&gt;Here is my server config &lt;code&gt;/etc/wireguard/wg0.conf&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cfg&#34; data-lang=&#34;cfg&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;[Interface]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Address = &lt;span style=&#34;font-style:italic&#34;&gt;192.168.2.1/24&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SaveConfig = &lt;span style=&#34;font-style:italic&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PostUp = &lt;span style=&#34;font-style:italic&#34;&gt;iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PostDown = &lt;span style=&#34;font-style:italic&#34;&gt;iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ListenPort = &lt;span style=&#34;font-style:italic&#34;&gt;51820&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PrivateKey = &lt;span style=&#34;font-style:italic&#34;&gt;&amp;lt;server_private_key&amp;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;font-weight:bold&#34;&gt;[Peer]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PublicKey = &lt;span style=&#34;font-style:italic&#34;&gt;&amp;lt;client_publick_key&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;AllowedIPs = &lt;span style=&#34;font-style:italic&#34;&gt;192.168.2.2/32&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;setting-up-my-arch-linux-client&#34;&gt;Setting up my Arch Linux client&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://wiki.archlinux.org/index.php/WireGuard&#34;&gt;WireGuard ArchWiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://tau.gr/posts/2019-03-03-set-up-cloudflared-ubuntu-wireguard/&#34;&gt;Set up cloudflared with WireGuard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.reddit.com/r/WireGuard/comments/g6yc1z/how_to_setup_wireguard_via_pihole_through_vpn/&#34;&gt;Pi-hole/WireGuard Reddit Post&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/notasausage/pi-hole-unbound-wireguard&#34;&gt;notasausage/pi-hole-unbound-wireguard&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;rsquo;m using the &lt;code&gt;linux-lts&lt;/code&gt; kernel so I ran the following.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;# pacman -S wireguard-tools wireguard-lts systemd-resolvconf
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;# systemctl enable systemd-resolved.service
# systemctl start systemd-resolved.service
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;My &lt;code&gt;/etc/wireguard/wg0.conf&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cfg&#34; data-lang=&#34;cfg&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;[Interface]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Address = &lt;span style=&#34;font-style:italic&#34;&gt;192.168.2.2/24&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PrivateKey = &lt;span style=&#34;font-style:italic&#34;&gt;&amp;lt;client_private_key&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;DNS = &lt;span style=&#34;font-style:italic&#34;&gt;192.168.2.1&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;font-weight:bold&#34;&gt;[Peer]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Endpoint = &lt;span style=&#34;font-style:italic&#34;&gt;mydomain.com:51820&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PublicKey = &lt;span style=&#34;font-style:italic&#34;&gt;&amp;lt;server_public_key&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;AllowedIPs = &lt;span style=&#34;font-style:italic&#34;&gt;0.0.0.0/0, ::/0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PersistentKeepalive = &lt;span style=&#34;font-style:italic&#34;&gt;21&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To use the connection:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;# wg-quick up wg0
# ... do things ...
# wg-quick down wg0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can also download the app for WireGuard on your phone and connect with it. You can generate a QR code to scan on your phone &lt;a href=&#34;https://www.wireguardconfig.com/qrcode&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I hope you got through it too! My ads don&amp;rsquo;t always block when I&amp;rsquo;m on my Arch Linux laptop unfortunately. Be sure to email me if you find the solution to that. Thanks for reading!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Formatting and reinstalling raspian on Raspberry Pi 3</title>
      <link>http://willvaughn.org/articles/formatting-and-reinstalling-raspian-on-raspberry-pi-3/</link>
      <pubDate>Sun, 02 Aug 2020 11:32:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/formatting-and-reinstalling-raspian-on-raspberry-pi-3/</guid>
      <description>&lt;p&gt;I am repurposing one of my Raspberry Pi&amp;rsquo;s and need to format the microSD card. I did this from my arch linux laptop.&lt;/p&gt;
&lt;h2 id=&#34;formatting-the-disk-with-parted&#34;&gt;Formatting the disk with &lt;code&gt;parted&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;I started from the official &lt;a href=&#34;https://www.raspberrypi.org/documentation/installation/&#34;&gt;Raspberry Pi Install Docs&lt;/a&gt; and that eventually linked me out to this &lt;a href=&#34;http://qdosmsq.dunbar-it.co.uk/blog/2013/06/noobs-for-raspberry-pi/&#34;&gt;blog&lt;/a&gt; by Norman Dunbar. I looked through it but decided to follow &lt;a href=&#34;https://linuxize.com/post/how-to-format-usb-sd-card-linux/&#34;&gt;this guide&lt;/a&gt; using &lt;a href=&#34;https://wiki.archlinux.org/index.php/Parted&#34;&gt;&lt;code&gt;parted&lt;/code&gt;&lt;/a&gt; to format the disk from the command line. I came back to Norman Dunbar&amp;rsquo;s blog later on for instructions on loading NOOBS onto the microSD in prep for installing raspian.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;# parted /dev/sda --script -- mklabel msdos
# parted /dev/sda --script -- mkpart primary fat32 1MiB 100%
# mkfs.vfat -F32 /dev/sda1
# parted /dev/sda print
Model: Generic- SD/MMC (scsi)
Disk /dev/sda: 31.9GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:

Number  Start   End     Size    Type     File system  Flags
 1      1049kB  31.9GB  31.9GB  primary  fat32        lba
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;loading-an-image-onto-the-microsd&#34;&gt;Loading an Image onto the microSD&lt;/h2&gt;
&lt;p&gt;I looked into the official instructions for installing boot images onto the microSD &lt;a href=&#34;https://www.raspberrypi.org/documentation/installation/installing-images/linux.md&#34;&gt;here&lt;/a&gt;. Those instructions are complicated and involve using &lt;code&gt;dd&lt;/code&gt; a whole lot. I decided I really don&amp;rsquo;t want to brick my laptop and I should use NOOBs. The Raspberry Pi docs link to this &lt;a href=&#34;http://qdosmsq.dunbar-it.co.uk/blog/2013/06/noobs-for-raspberry-pi/&#34;&gt;blog&lt;/a&gt; by Norman Dunbar for loading NOOBs onto the disk, it&amp;rsquo;s pretty easy.&lt;/p&gt;
&lt;p&gt;Verify the sha1 of the downloaded NOOBS zip is the same as the one on the downloads page.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;$ sha1sum ~/Downloads/NOOBS_v3_4_0.zip
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Find where the disk is mounted.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;$ mount | grep -i sda
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For me, this informed me that I needed to go here to extract the NOOBS zip.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;$ cd /run/media/nackjicholson/571C-B47B
$ unzip ~/Downloads/NOOBS_v3_4_0.zip
$ cd ~
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Unmounting the disk.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;# unmount /dev/sda
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Done! This microSD is ready for the pi.&lt;/p&gt;
&lt;h2 id=&#34;installing-raspian-with-noobs&#34;&gt;Installing Raspian with NOOBS&lt;/h2&gt;
&lt;p&gt;Start up the Raspberry Pi 3 with the NOOBS disk, follow the easy to use application to install an OS.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The git-diff manual review</title>
      <link>http://willvaughn.org/articles/the-git-diff-manual-review/</link>
      <pubDate>Sun, 22 Mar 2020 17:07:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/the-git-diff-manual-review/</guid>
      <description>&lt;p&gt;This is a fairly short, but informative, manual for a powerful command in the git arsenal. At its simplest the manual explains the following uses of &lt;code&gt;git-diff&lt;/code&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Show changes between the working tree and the index (or another tree).&lt;/p&gt;
&lt;p&gt;AKA What you could tell git to add to the staging area for a commit.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 diff
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Show changes between the index and tree.&lt;/p&gt;
&lt;p&gt;AKA Show what is staged for the next commit.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 diff --cached HEAD
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Show changes between two trees.&lt;/p&gt;
&lt;p&gt;AKA Show difference in between commits&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;font-style:italic&#34;&gt;# Show diff for the last few commits to where our branch is now.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git diff HEAD~3 HEAD
&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;font-style:italic&#34;&gt;# For ranges&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git diff 9a29ab57 HEAD
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git diff 9a29ab57..HEAD
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Show changes between two blob objects.&lt;/p&gt;
&lt;p&gt;AKA diff specific files.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;font-style:italic&#34;&gt;# Show changes to the config.toml file in the last 3 commits.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git diff HEAD~3..HEAD -- ./config.toml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Show changes between two files on disk.&lt;/p&gt;
&lt;p&gt;AKA Show difference in your working tree, to what&amp;rsquo;s in a commit.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;font-style:italic&#34;&gt;# What has changed about these files.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git diff HEAD -- ./config.toml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git diff HEAD~3 -- ./blog.org
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The way I wrote these here is close to how they&amp;rsquo;re written in the manual. Understanding &lt;code&gt;git-diff&lt;/code&gt; is aided by understanding the flow of git commits and objects; concepts like the index (staging area), the working tree, and references. I suggest reviewing the &lt;code&gt;gittutorial&lt;/code&gt; manuals to brush up on these concepts if you need to.&lt;/p&gt;
&lt;p&gt;Some other highlights of the manual:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In depth examples of diff output formats.&lt;/li&gt;
&lt;li&gt;Options like &lt;code&gt;--stat&lt;/code&gt; and &lt;code&gt;--shortstat&lt;/code&gt; for at a glance change information.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--ignore-all-space&lt;/code&gt; for ignoring whitespace changes.&lt;/li&gt;
&lt;li&gt;in the weeds info about diff algorithm options.&lt;/li&gt;
&lt;li&gt;Some options that really only exist for writing scripts against.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks for reading this manual review! Be well.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Arch Linux LTS Kernel</title>
      <link>http://willvaughn.org/articles/arch-linux-lts-kernel/</link>
      <pubDate>Sat, 04 Jan 2020 18:59:00 -0800</pubDate>
      
      <guid>http://willvaughn.org/articles/arch-linux-lts-kernel/</guid>
      <description>&lt;h2 id=&#34;preparation&#34;&gt;Preparation&lt;/h2&gt;
&lt;p&gt;In order to stop my system from continuing to update the original linux kernel, I edited the ignored packages list in my &lt;code&gt;/etc/pacman.conf&lt;/code&gt; file.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cfg&#34; data-lang=&#34;cfg&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;IgnorePkg   = &lt;span style=&#34;font-style:italic&#34;&gt;linux&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then I ran an update to the system.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 pacman -Syu
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;installing-the-lts-kernel&#34;&gt;Installing the LTS Kernel&lt;/h2&gt;
&lt;p&gt;Using pacman to install the LTS kernel package.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 pacman -S linux-lts
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;m using a standard boot loader that stores configs in &lt;em&gt;/boot/loader/loader.conf&lt;/em&gt;. I needed to inform my boot loader configuration to load the new LTS kernel I just installed when booting up. My &lt;em&gt;loader.conf&lt;/em&gt; points at another config at &lt;em&gt;/boot/loader/entries/arch.conf&lt;/em&gt; which I needed to edit the following lines.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;/boot/loader/entries/arch.conf&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cfg&#34; data-lang=&#34;cfg&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;title Arch Linux (ENCRYPTED)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;linux /vmlinuz-linux-lts
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;initrd /initramfs-linux-lts.img
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The final step was to reboot my system.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-sr&#34; data-lang=&#34;sr&#34;&gt;reboot
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Once my machine was restarted it was using the &lt;code&gt;linux-lts&lt;/code&gt; kernel.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;uname -rs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;# Linux 4.19.92-1-lts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>The tmux manual review</title>
      <link>http://willvaughn.org/articles/the-tmux-manual-review/</link>
      <pubDate>Wed, 04 Dec 2019 17:26:00 -0800</pubDate>
      
      <guid>http://willvaughn.org/articles/the-tmux-manual-review/</guid>
      <description>&lt;p&gt;The tmux manual is extensive, well written, and informative. It is an excellent reference document, but I don&amp;rsquo;t think it is particularly well-suited to teaching the concepts of tmux and how those concepts can be used as part of a user&amp;rsquo;s personal workflow.&lt;/p&gt;
&lt;p&gt;The most useful thing I can say to the uninitiated person curious about tmux is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Tmux does for terminal windows what your Desktop OS does for application windows. It helps you organize, partition, and navigate your terminal windows in a way that allows you to background tasks and switch your focus effectively.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you consistently have more than two terminal windows or tabs open, you can benefit from the hour or so it takes to learn the basics of tmux. Here are a few links to get you going.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://leanpub.com/the-tao-of-tmux/read&#34;&gt;Tao of Tmux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://man.openbsd.org/OpenBSD-current/man1/tmux.1&#34;&gt;tmux manual&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/tmux-python/tmuxp&#34;&gt;tmuxp&lt;/a&gt; session manager&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You are also welcome to use my &lt;code&gt;.tmux.conf&lt;/code&gt; as inspiration for your own. It is available &lt;a href=&#34;https://gitlab.com/willvaughn/dotfiles/blob/master/tmux.conf&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;concepts&#34;&gt;Concepts&lt;/h2&gt;
&lt;p&gt;Here is the hierarchy of the tmux system.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;server
&lt;ul&gt;
&lt;li&gt;sessions
&lt;ul&gt;
&lt;li&gt;windows
&lt;ul&gt;
&lt;li&gt;panes&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When &amp;ldquo;attaching&amp;rdquo; to tmux, you do so as a client of the server. The server contains multiple named sessions which it can share amongst clients. Each session has a collection of windows and panes. For me, sessions are how I organize my projects. I usually have a tmux session available for each project I&amp;rsquo;m working on. Switching sessions equates to switching projects. This way I&amp;rsquo;m focusing on one project/session at a time, but can easily switch to another when I need to without losing my progress. Within a session, I keep multiple windows that help me organize the different subtasks I have to do related to the project. This could be things like starting a webserver or a text editor. Finally, panes are for viewing two terminal instances next to each other on the same screen. You can have your text editor open on the left pane, and the command line open on the right pane.&lt;/p&gt;
&lt;p&gt;The Tao of Tmux book has some excellent visualizations which help clarify this organization of terminal instance.&lt;/p&gt;
&lt;h2 id=&#34;basics-of-tmux&#34;&gt;Basics of tmux&lt;/h2&gt;
&lt;h3 id=&#34;the-prefix&#34;&gt;The prefix&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;prefix&lt;/code&gt; is a key combination which signals that you want to do something within tmux. Before typing a tmux command, you always hit the prefix first. The default prefix is &lt;code&gt;C-b&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;essential-commands&#34;&gt;Essential commands&lt;/h3&gt;
&lt;p&gt;Once you&amp;rsquo;ve hit the prefix, then you can hit another key or set of keys to perform an action in tmux.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;command&lt;/th&gt;
          &lt;th&gt;description&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;?&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Show all the available tmux commands&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;s&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Opens menu to switch sessions&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;d&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Detach from session&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;c&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Create a new window&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;n&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Next window&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;p&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Previous window&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;%&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Vertical split window into panes&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;&amp;quot;&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Horizontal split window into panes&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;Up&lt;/code&gt; &lt;code&gt;Down&lt;/code&gt; &lt;code&gt;Left&lt;/code&gt; &lt;code&gt;Right&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Navigate panes&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;x&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Close pane (with confirm)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;&amp;amp;&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Close window (with confirm)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;,&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Rename window&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;:&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Execute commands&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;swapw -s 1 -t 0&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Swap windows&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;neww -c &amp;lt;path&amp;gt; -n &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Create a new window and set its name and cwd&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Enter copy mode&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;See the manual for more about copy mode. One way I use this copy mode is to dump all of my interesting terminal output to a file that I want to save or share.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enter copy mode &lt;code&gt;Prefix+[&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gg&lt;/code&gt; to go to the top of the file&lt;/li&gt;
&lt;li&gt;&lt;code&gt;V&lt;/code&gt; to enter visual block mode&lt;/li&gt;
&lt;li&gt;&lt;code&gt;G&lt;/code&gt; go back down to the last line&lt;/li&gt;
&lt;li&gt;&lt;code&gt;M-w&lt;/code&gt; Copy the text to buffer (kill-ring) (I have this as bound to &lt;code&gt;y&lt;/code&gt; for obvious reasons)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Prefix+:&lt;/code&gt; and &lt;code&gt;:save-buffer ~/path/to/output.txt&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;about-session-managers&#34;&gt;About session managers&lt;/h2&gt;
&lt;p&gt;There are a few session manager tools out there for tmux, and all of them address the central issue of being able to save tmux session configurations. It can be a drag to restart your computer and then try to &lt;code&gt;tmux at -t my-project&lt;/code&gt; only to find that all of the windows and panes that you so carefully created have been annihilated. Using a session manager can help alleviate that pain. My personal favorite is &lt;code&gt;tmuxp&lt;/code&gt; because it is written in python and has the &lt;code&gt;tmuxp freeze&lt;/code&gt; feature to export the current session to a file. Session managers are not required, you don&amp;rsquo;t have to install one right away. Go try tmux for a while, if you find that you get annoyed when you lose a session &amp;ndash; install a session manager!&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I can&amp;rsquo;t emphasize enough that you should take a few hours to read &lt;em&gt;The Tao of Tmux&lt;/em&gt; book. It is a much more thorough walkthrough of tmux concepts than I gave here. It has illustrations and examples that will illuminate the ways you can use tmux to do whatever fits your workflow. Best of luck on your journey with tmux! Thanks for reading!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Emacs wisdom from the internet</title>
      <link>http://willvaughn.org/articles/emacs-wisdom-from-the-internet/</link>
      <pubDate>Sat, 30 Nov 2019 15:25:00 -0800</pubDate>
      
      <guid>http://willvaughn.org/articles/emacs-wisdom-from-the-internet/</guid>
      <description>&lt;p&gt;This is a collection of useful things I learned while searching the web for how to do something in Emacs. This blog is my effort to better remember and share these lessons.&lt;/p&gt;
&lt;h2 id=&#34;the-basics-of-emacs-copy-paste&#34;&gt;The basics of Emacs copy/paste&lt;/h2&gt;
&lt;p&gt;Start visual selection &lt;code&gt;C-SPC&lt;/code&gt; then navigate to end of selection.&lt;br /&gt;
&lt;code&gt;M-w&lt;/code&gt; puts that text in the kill ring without deleting it. (Copy)&lt;br /&gt;
&lt;code&gt;C-w&lt;/code&gt; puts that test in the kill ring and deletes it. (Cut)&lt;br /&gt;
&lt;code&gt;C-y&lt;/code&gt; will &amp;ldquo;yank&amp;rdquo; that text out of the kill ring back into the buffer. (Paste)&lt;/p&gt;
&lt;h2 id=&#34;org-mode&#34;&gt;Org Mode&lt;/h2&gt;
&lt;h3 id=&#34;sparse-tree-search-and-tags&#34;&gt;Sparse tree search and tags&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://orgmode.org/manual/Sparse-trees.html&#34;&gt;https://orgmode.org/manual/Sparse-trees.html&lt;/a&gt;
&lt;a href=&#34;https://orgmode.org/manual/Tag-Searches.html#Tag-Searches&#34;&gt;https://orgmode.org/manual/Tag-Searches.html#Tag-Searches&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;C-c / m&lt;/code&gt; then the tag value.&lt;/p&gt;
&lt;p&gt;Exiting a sparse tree is kind of weird but can be accomplished with &lt;code&gt;C-c C-c&lt;/code&gt; and some &lt;code&gt;Shift+Tab&lt;/code&gt; to cycle visibilities.&lt;/p&gt;
&lt;h3 id=&#34;narrowing-scope&#34;&gt;Narrowing Scope&lt;/h3&gt;
&lt;p&gt;Learn more: &lt;a href=&#34;https://emacs.stackexchange.com/questions/21353/in-org-mode-is-there-a-way-to-narrow-the-buffer-to-just-the-text-under-a-headin&#34;&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;C-x n s&lt;/code&gt; To narrow a org mode to items under a single header&lt;/p&gt;
&lt;p&gt;&lt;code&gt;C-x n w&lt;/code&gt; To widen it back out. :praise:&lt;/p&gt;
&lt;h3 id=&#34;date-and-time-insertion&#34;&gt;Date and Time insertion&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;C-c !&lt;/code&gt; Insert the current date&lt;/p&gt;
&lt;p&gt;&lt;code&gt;C-u C-c !&lt;/code&gt; Will get you the current date and time!&lt;/p&gt;
&lt;h3 id=&#34;archiving-done-items&#34;&gt;Archiving &lt;code&gt;DONE&lt;/code&gt; items&lt;/h3&gt;
&lt;p&gt;Learn more: &lt;a href=&#34;https://orgmode.org/manual/Moving-subtrees.html#Moving-subtrees&#34;&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;C-c C-x C-a&lt;/code&gt; Archive a single item.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;C-u C-c C-x C-s&lt;/code&gt;. Prompts for archives of items with status DONE. This can also be shortened to &lt;code&gt;C-u C-c $&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;adding-a-created-property-timestamp-to-an-org-item-after-it-was-made&#34;&gt;Adding a CREATED property timestamp to an org item after it was made&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Add the CREATED property &lt;code&gt;C-C C-x p&lt;/code&gt; , choose created, nil&lt;/li&gt;
&lt;li&gt;Go edit it and do &lt;code&gt;C-u C-c !&lt;/code&gt; to insert the timestamp.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;vim-evil&#34;&gt;VIM/EVIL&lt;/h2&gt;
&lt;h3 id=&#34;selecting-and-changing-quoted-strings-dot&#34;&gt;Selecting and changing quoted strings.&lt;/h3&gt;
&lt;p&gt;Learn more: &lt;a href=&#34;https://stackoverflow.com/questions/1444054/in-vim-is-there-a-plugin-to-use-to-match-the-corresponding-double-quote&#34;&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;va&amp;quot;&lt;/code&gt; visually select string including the quotes.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vi&amp;quot;&lt;/code&gt; visually select the content of the string.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ci&amp;quot;&lt;/code&gt; change the content of the string, between the quotes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;substitution&#34;&gt;Substitution&lt;/h3&gt;
&lt;p&gt;Replace from the current line to the end of the file: &lt;code&gt;:.,$s/target/replacement/g&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Replace in the region all occurrences: &lt;code&gt;:&#39;&amp;lt;,&#39;&amp;gt;s/target/replacement/g&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can do this by visually selecting and then pressing &lt;code&gt;:&lt;/code&gt; to enter ex mode.&lt;/p&gt;
&lt;h3 id=&#34;motion&#34;&gt;Motion&lt;/h3&gt;
&lt;p&gt;Remember to move around with &lt;code&gt;{&lt;/code&gt; and &lt;code&gt;}&lt;/code&gt;. Moving by code blocks/paragraphs.&lt;/p&gt;
&lt;h2 id=&#34;ivy-mode&#34;&gt;Ivy Mode&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;C-M-j&lt;/code&gt; Don&amp;rsquo;t use the selection, just enter the text you&amp;rsquo;ve written!&lt;/p&gt;
&lt;h2 id=&#34;man&#34;&gt;man&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;M-x man&lt;/code&gt; Opening man pages.&lt;/p&gt;
&lt;h2 id=&#34;ispell-spell-check&#34;&gt;ispell spell check&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;brew install ispell
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;M-x ispell&lt;/code&gt; to run the spell checker.
Press &lt;code&gt;A&lt;/code&gt; to accept a word for session. Use numbers in prompt at the top of the screen to select the suggestions.&lt;/p&gt;
&lt;h2 id=&#34;undo-tree&#34;&gt;Undo Tree&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;C-_&lt;/code&gt; is undo. You can visualize the tree of things you undo. It&amp;rsquo;s &lt;code&gt;C-x u&lt;/code&gt;. You can then move around that buffer, and the buffer you were editing gets previewed at each place in the undo tree.&lt;/p&gt;
&lt;h2 id=&#34;info-mode&#34;&gt;Info mode&lt;/h2&gt;
&lt;p&gt;I cloned &lt;a href=&#34;https://github.com/webframp/sicp-info&#34;&gt;https://github.com/webframp/sicp-info&lt;/a&gt; and then I can read it in emacs by opening the .info buffer and running:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;M-x Info-on-current-buffer&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;python-debugging&#34;&gt;Python Debugging&lt;/h2&gt;
&lt;p&gt;Be in a file you want to run the debugger from. Or you can use &lt;code&gt;M-x cd&lt;/code&gt; to change your working directory. To start the emacs pdb integration type &lt;code&gt;M-x pdb&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This will prompt you in the minibuffer with:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;Run pdb (like this?): pdb
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You want to replace that &lt;code&gt;pdb&lt;/code&gt; part with:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;Run pdb (like this?): python -m pdb your_code.py
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;OR&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;Run pdb (like this?): python -m pdb -m module.path.to.your_code
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That is going to kick you into the pdb prompt. Now you need to type &lt;code&gt;help&lt;/code&gt; and read the &lt;a href=&#34;https://docs.python.org/3/library/pdb.html&#34;&gt;pdb docs&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Arch Linux First Steps</title>
      <link>http://willvaughn.org/articles/arch-linux-first-steps/</link>
      <pubDate>Sat, 30 Nov 2019 13:41:00 -0800</pubDate>
      
      <guid>http://willvaughn.org/articles/arch-linux-first-steps/</guid>
      <description>&lt;p&gt;This follows my last post &lt;a href=&#34;http://willvaughn.org/articles/arch-linux-on-my-lenovo-t470s&#34;&gt;Arch Linux on my Lenovo t470s&lt;/a&gt; with more details about my own personal setup with Arch Linux. I use GNOME and really like it, if you&amp;rsquo;re new to Linux I think it&amp;rsquo;s a comfortable entry into the space, and if you&amp;rsquo;re not new it&amp;rsquo;s still extremely ergonomic, capable and comfortable.&lt;/p&gt;
&lt;h2 id=&#34;enable-system-networkmanager&#34;&gt;Enable system NetworkManager&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 enable NetworkManager
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemctl start NetworkManager
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nmtui &lt;span style=&#34;font-style:italic&#34;&gt;# terminal ui to activate and connect to wifi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;install-zsh&#34;&gt;Install &lt;code&gt;zsh&lt;/code&gt;&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;pacman -S zsh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;user-and-groups-setup&#34;&gt;User and groups setup&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://wiki.archlinux.org/index.php/Users_and_groups#User_management&#34;&gt;https://wiki.archlinux.org/index.php/Users_and_groups#User_management&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;useradd -m -g wheel -s /usr/bin/zsh &amp;lt;USERNAME&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;passwd &amp;lt;USERNAME&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Go edit the sudoers file with &lt;code&gt;EDITOR=vim visudo&lt;/code&gt; and comment out the &lt;code&gt;%wheel&lt;/code&gt; line. It will add all users in the wheel group to the sudoers.&lt;/p&gt;
&lt;h2 id=&#34;install-gnome-and-gnome-extra&#34;&gt;Install &lt;code&gt;gnome&lt;/code&gt; and &lt;code&gt;gnome-extra&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://wiki.archlinux.org/index.php/GNOME&#34;&gt;https://wiki.archlinux.org/index.php/GNOME&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;pacman -S gnome gnome-extra
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Enable gdm &lt;a href=&#34;https://wiki.archlinux.org/index.php/GDM&#34;&gt;https://wiki.archlinux.org/index.php/GDM&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 enable gdm.service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;reboot
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Should see the GNOME login managed by gdm.&lt;/p&gt;
&lt;p&gt;Now in order for ``totem`` to work aka GNOME Videos app to play H256 mp4 vids install ``gst-libav``&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 pacman -S gst-libav
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;install-firefox-and-firefox-developer-edition&#34;&gt;install &lt;code&gt;firefox&lt;/code&gt; and &lt;code&gt;firefox-developer-edition&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://wiki.archlinux.org/index.php/firefox&#34;&gt;https://wiki.archlinux.org/index.php/firefox&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;pacman -S firefox firefox-developer-edition
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;install-python3&#34;&gt;install python3&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://wiki.archlinux.org/index.php/Python&#34;&gt;https://wiki.archlinux.org/index.php/Python&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;setup-git-github-and-gitlab&#34;&gt;Setup git, github and gitlab&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://help.github.com/en/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent&#34;&gt;https://help.github.com/en/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://help.github.com/en/github/authenticating-to-github/adding-a-new-ssh-key-to-your-github-account&#34;&gt;https://help.github.com/en/github/authenticating-to-github/adding-a-new-ssh-key-to-your-github-account&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://help.github.com/en/github/authenticating-to-github/testing-your-ssh-connection&#34;&gt;https://help.github.com/en/github/authenticating-to-github/testing-your-ssh-connection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.gitlab.com/ee/gitlab-basics/create-your-ssh-keys.html&#34;&gt;https://docs.gitlab.com/ee/gitlab-basics/create-your-ssh-keys.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Need &lt;code&gt;xclip&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;pacman -S xclip
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Arch Linux on my Lenovo t470s</title>
      <link>http://willvaughn.org/articles/arch-linux-on-my-lenovo-t470s/</link>
      <pubDate>Sat, 30 Nov 2019 13:40:00 -0800</pubDate>
      
      <guid>http://willvaughn.org/articles/arch-linux-on-my-lenovo-t470s/</guid>
      <description>&lt;h2 id=&#34;install&#34;&gt;Install&lt;/h2&gt;
&lt;p&gt;Arch Linux is a rolling update distribution of Linux with great documentation, and a minimalist approach. I gravitate toward tools which encourage me to start small and gradually grow my understanding and skills. Arch is maybe even a little extreme for me in that regard, after installing Arch you have a system that is so bare bones it isn&amp;rsquo;t even useful. You then have all the choices in the world for how to set it up. This blog and my next one, &lt;a href=&#34;http://willvaughn.org/articles/arch-linux-first-steps&#34;&gt;Arch Linux First Steps&lt;/a&gt;, is documentation of the choices I made for my system.&lt;/p&gt;
&lt;p&gt;This was written during my second install of Arch Linux on this laptop. I allowed my previous install to get stale for about 8 months. Arch Linux, being a rolling update distribution, was mad at me when I tried to update it after so long.&lt;/p&gt;
&lt;p&gt;My first install was based on this helpful &lt;a href=&#34;https://gist.github.com/kylemanna/cde147d777d243b82a85e9ac16b85458&#34;&gt;gist&lt;/a&gt; of instructions. For this second round I am following along with this &lt;a href=&#34;https://www.youtube.com/watch?v=dva-7SCYTqY&#34;&gt;youtube video&lt;/a&gt; as well.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WARNING&lt;/strong&gt; This is also an install where I completely wiped my computer including the prior Windows OS. If you want a dual boot system some of these steps might still work but you&amp;rsquo;ll probably want to find another example of a dual boot Arch install.&lt;/p&gt;
&lt;h3 id=&#34;download-iso&#34;&gt;Download ISO&lt;/h3&gt;
&lt;p&gt;I curled down the PGP key here: &lt;a href=&#34;https://www.archlinux.org/download/&#34;&gt;https://www.archlinux.org/download/&lt;/a&gt;
And the ISO image here: &lt;a href=&#34;https://mirrors.ocf.berkeley.edu/archlinux/iso/2019.11.01/&#34;&gt;https://mirrors.ocf.berkeley.edu/archlinux/iso/2019.11.01/&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;gpg --keyserver-options auto-key-retrieve --verify archlinux-2019.11.01-x86_64.iso.sig
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;load-iso-onto-usb-flash-drive-dot&#34;&gt;Load ISO onto USB flash drive.&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;diskutil unmountDisk /dev/disk2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dd &lt;span style=&#34;font-weight:bold&#34;&gt;if&lt;/span&gt;=path/to/arch.iso of=/dev/rdisk2 bs=1m
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;load-on-lenovo-thinkpad-t470s&#34;&gt;Load on Lenovo Thinkpad t470s&lt;/h3&gt;
&lt;p&gt;When the Lenovo logo shows up hit &lt;code&gt;F12&lt;/code&gt; to enter the &amp;ldquo;BOOT Menu&amp;rdquo;. Select the USB Drive.&lt;/p&gt;
&lt;h3 id=&#34;setup-the-wifi-connection-dot&#34;&gt;Setup the wifi connection.&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;wifi-menu
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;create-partitions&#34;&gt;Create Partitions&lt;/h3&gt;
&lt;p&gt;Check the disk out a bit.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;lsblk
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;nvme0n1&lt;/code&gt; device for me has 238.5G, where &lt;code&gt;nvme0n1p1&lt;/code&gt; is 1G for boot and &lt;code&gt;nvme0n1p2&lt;/code&gt; is 237.5G. Remember, I&amp;rsquo;m documenting this during a re-install and it will likely look different for you.&lt;/p&gt;
&lt;p&gt;Using &lt;code&gt;cgdisk /dev/nvme0n1&lt;/code&gt; I was shown:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;1 1024.0 MiB EFI System boot
2 237.5 GiB Linux filesystem root
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I want to clear these and recreate these partions in order to re-install Arch from scratch. So I navigated in &lt;code&gt;cgdisk /dev/nvme0n1&lt;/code&gt; to both and deleted them. I then created new partitions with the following details.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;2048 -&amp;gt; 512M guid: ef00 name: boot EFI
all the rest guid: 8e00 (for LVM) name: Arch LVM
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Create the EFI partition filesystem&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;mkfs.vfat -F32 -n EFI /dev/nvme0n1p1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;setup-the-encryption&#34;&gt;Setup the encryption&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;cryptsetup -y -v luksFormat /dev/nvme0n1p2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cryptsetup open --typ luks /dev/nvme0n1p2 archlv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;# check it&amp;#39;s there&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ls /dev/mapper/archlv
&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;font-style:italic&#34;&gt;# create physical volume&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pvcreate /dev/mapper/archlv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-style:italic&#34;&gt;# create virtual group&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;vgcreate archvg /dev/mapper/archlv
&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;font-style:italic&#34;&gt;# Under the vg, you create logical volumes.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lvcreate -L16G archvg -n swap
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lvcreate -L30G archvg -n root
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lvcreate -l 100%FREE archvg -n home
&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;font-style:italic&#34;&gt;# Then list the block to see what you&amp;#39;ve done.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lsblk
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Should have an &lt;code&gt;archlv&lt;/code&gt; and the vgs listed under the &lt;code&gt;/dev/nvme0n1p2&lt;/code&gt; drive.&lt;/p&gt;
&lt;h3 id=&#34;file-systems&#34;&gt;File systems&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;mkfs.ext4 /dev/mapper/archvg-root
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkfs.ext4 /dev/mapper/archvg-home
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkswap /dev/mapper/archvg-swap
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;swapon /dev/mapper/archvg-swap
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Check that with &lt;code&gt;free -m&lt;/code&gt; to see the swap and free memory.&lt;/p&gt;
&lt;h3 id=&#34;mount&#34;&gt;Mount&lt;/h3&gt;
&lt;p&gt;These steps actually mount everything we&amp;rsquo;ve been doing in the ISO install disk onto the computers filesystem.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;mount /dev/mapper/archvg-root /mnt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir /mnt/boot
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mount /dev/nvme0n1p1 /mnt/boot
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir /mnt/home
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mount /dev/mapper/archvg-home /mnt/home
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;install-base-system&#34;&gt;Install base system&lt;/h3&gt;
&lt;h4 id=&#34;install-reflector-and-set-the-mirrorlist&#34;&gt;Install reflector and set the mirrorlist&lt;/h4&gt;
&lt;p&gt;This tool is awesome, was happy to learn of it. My first time installing Arch I didn&amp;rsquo;t know anything about the mirrorlist and I had slow download speeds.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;pacman -S reflector
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;reflector -c &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;United States&amp;#39;&lt;/span&gt; -f 12 -l 12 --verbose --save /etc/pacman.d/mirrorlist
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Use &lt;code&gt;reflector --help&lt;/code&gt; to somewhat understand what&amp;rsquo;s happening here.&lt;/p&gt;
&lt;h4 id=&#34;install-base-arch-to-mnt&#34;&gt;Install base arch to &lt;code&gt;/mnt&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Installs some basics into our minimal install.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;pacstrap /mnt base base-devel linux linux-firmware intel-ucode sudo emacs vim tmux git networkmanager
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Check it out with &lt;code&gt;ls /mnt&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Generate a filesystem table.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; I learned later that I maybe should have used UUIDs in my filesystem table with the &lt;code&gt;-U&lt;/code&gt; flag.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;genfstab -p /mnt &amp;gt;&amp;gt; /mnt/etc/fstab
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Check that out with &lt;code&gt;cat /mnt/etc/fstab&lt;/code&gt;&lt;/p&gt;
&lt;h4 id=&#34;enter-and-setup-the-new-system&#34;&gt;Enter and setup the new system&lt;/h4&gt;
&lt;p&gt;Signs us out of the ISO and into our Arch install. Woot!&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;arch-chroot /mnt
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Setup the clock.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;ln -s /usr/share/zoneinfo/America/Los_Angeles /etc/localtime
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hwclock --systohc --utc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Set root password with &lt;code&gt;passwd&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Edit &lt;code&gt;vim /etc/locale.gen&lt;/code&gt; to uncomment the &lt;code&gt;en_US.UTF-8 UTF-8&lt;/code&gt; and &lt;code&gt;en_US ISO-8859-1&lt;/code&gt; lines. Then run &lt;code&gt;locale-gen&lt;/code&gt; and &lt;code&gt;locale &amp;gt; /etc/locale.conf&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Set the hostname: &lt;code&gt;echo &amp;quot;nackjicholson&amp;quot; &amp;gt; /etc/hostname&lt;/code&gt;
Edit the hosts file with vim.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;/etc/hosts&lt;/em&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;# Static table lookup for hostnames.
# See hosts(5) for details.
127.0.0.1 nackjicholson.localdomain nackjicholson
::1 nackjicholson.localdomain nackjicholson
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Configure &lt;code&gt;mkinitcpio&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Edit the &amp;ldquo;HOOKS&amp;rdquo; line in &lt;code&gt;vim /etc/mkinitcpio.conf&lt;/code&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;HOOKS=(base udev autodetect modconf block keyboard encrypt lvm2 filesystems fsck)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And run the following to generate the ramdisks.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;mkinitcpio -p linux
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt; For some reason this didn&amp;rsquo;t work for me, failing with &amp;ldquo;ERROR: Hook &amp;rsquo;lvm2&amp;rsquo; cannot be found. I had to do &lt;code&gt;pacman -S lvm2&lt;/code&gt; and then try again.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;bootctl --path=/boot/ install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now edit &lt;code&gt;vim /boot/loader/loader.conf&lt;/code&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;default arch
timeout 5
editor 0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Apparently that &lt;code&gt;editor 0&lt;/code&gt; disables a tricky hack I don&amp;rsquo;t really understand about entering the kernel. Okie doke!&lt;/p&gt;
&lt;p&gt;Now edit &lt;code&gt;vim /boot/loader/entries/arch.conf&lt;/code&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;title Arch Linux (ENCRYPTED)
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
options cryptdevice=UUID=XXXX:archlv root=/dev/mapper/archvg-root quiet rw
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To get the value of the UUID in there, you use &lt;code&gt;:read ! blkid /dev/nvme0n1p2&lt;/code&gt; from within vim.&lt;/p&gt;
&lt;p&gt;Reboot!&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;exit &lt;span style=&#34;font-style:italic&#34;&gt;# exit arch-chroot&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;umount -R /mnt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;reboot
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Login as &lt;code&gt;root&lt;/code&gt; user with the password you set.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This is a minimal install of a Arch Linux on an SSD nvme disk. I hope it all worked for you too! Feel free to email me with any corrections or issues you faced. Check out my &lt;a href=&#34;http://willvaughn.org/articles/arch-linux-first-steps&#34;&gt;next entry&lt;/a&gt; on my own personal first steps on Arch Linux, things like installing the GNOME desktop environment and setting up the WiFi and such. Thanks for reading!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The git-rebase manual review</title>
      <link>http://willvaughn.org/articles/the-git-rebase-manual-review/</link>
      <pubDate>Fri, 22 Nov 2019 21:25:00 -0800</pubDate>
      
      <guid>http://willvaughn.org/articles/the-git-rebase-manual-review/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve spent most of my career being scared of &lt;code&gt;git rebase&lt;/code&gt;. I looked on with envy as my git wizard colleagues used it like magic to rewrite history and time travel. The few times I mustered enough courage to imitate them I would rebase myself into a broken branch, a detached HEAD, and lost work. I simply gave up on rebase and decided that &lt;code&gt;git merge&lt;/code&gt; was more my speed.&lt;/p&gt;
&lt;p&gt;In the last six months I&amp;rsquo;ve made a concerted effort to read the manual and actually learn to use rebase from first principles. It has become an important part of my git workflow, allowing me to present cleaner pull requests and tell more compelling stories with my commits. The most useful realizations in my journey with rebase have been:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Rebase really means &amp;ldquo;move&amp;rdquo; commits.&lt;/li&gt;
&lt;li&gt;The word &amp;ldquo;move&amp;rdquo; can also mean &amp;ldquo;redo&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;No one writes clean git logs organically.&lt;/li&gt;
&lt;li&gt;Rebase is easier to manage when conflicts are unlikely.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;moving-commits&#34;&gt;Moving commits&lt;/h2&gt;
&lt;p&gt;Consider you&amp;rsquo;ve branched off &lt;code&gt;master&lt;/code&gt; to a branch called &lt;code&gt;my-new-work&lt;/code&gt;. When you&amp;rsquo;ve completed your work, you&amp;rsquo;d like to incorporate the changes that others have made since you diverged from &lt;code&gt;master&lt;/code&gt;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;      A---B---C my-new-work
     /
D---E---F---G master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There are a few different ways to do this. The way I would &lt;strong&gt;ALWAYS&lt;/strong&gt; do this prior to learning the semantics of rebase was to merge the changes from commit &amp;ldquo;G&amp;rdquo; into &lt;code&gt;my-new-work&lt;/code&gt;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;git merge master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To arrive at a merge commit &amp;ldquo;X&amp;rdquo;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;      A---B---C---X my-new-work
     /           /
D---E---F-------G master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now it is time to put in a pull request to incorporate &lt;code&gt;my-new-work&lt;/code&gt; into master. However, pull requests lead to feedback, which lead to a new change, which leads to a new commit &amp;ldquo;H&amp;rdquo;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;      A---B---C---X---H my-new-work
     /           /
D---E---F-------G master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After I have made &amp;ldquo;H&amp;rdquo;, somebody else merged new code to &lt;code&gt;master&lt;/code&gt; with commits &amp;ldquo;I&amp;rdquo; and &amp;ldquo;J&amp;rdquo;. I need those changes to make sure everything still works.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;      A---B---C---X---H my-new-work
     /           /
D---E---F-------G---I---J master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So, I have to run &lt;code&gt;git merge master my-new-work&lt;/code&gt; to get the code from &amp;ldquo;I&amp;rdquo; and &amp;ldquo;J&amp;rdquo;. I end up with another merge commit &amp;ldquo;Y&amp;rdquo;. Any merge conflicts which happen during this process have to be resolved before you can make commit &amp;ldquo;Y&amp;rdquo;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;      A---B---C---X---H---Y my-new-work
     /           /       /
D---E---F-------G---I---J master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, my pull request is approved and I can hit the button to merge &lt;code&gt;my-new-work&lt;/code&gt; into &lt;code&gt;master&lt;/code&gt;; creating merge commit &amp;ldquo;Z&amp;rdquo;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;      A---B---C---X---H---Y my-new-work
     /           /       / \
D---E---F-------G---I---J---Z master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is fine, in a way it&amp;rsquo;s simple because it accurately describes exactly what happened at every point in the time line, without any funny business or trickery. This process has worked for me for about 10 years, and I have never really been forced to give it a second thought. The way &lt;code&gt;git rebase&lt;/code&gt; differs is that it lets you pretend you didn&amp;rsquo;t start &lt;code&gt;my-new-work&lt;/code&gt; until after commit &amp;ldquo;J&amp;rdquo; occurred. It allows you to alter (or move) where it appears that you branched off from master. Let&amp;rsquo;s go through this set of commits again using &lt;code&gt;git-rebase&lt;/code&gt; instead of &lt;code&gt;git merge&lt;/code&gt;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;      A---B---C my-new-work
     /
D---E---F---G master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Before putting in the pull request, I run &lt;code&gt;git rebase master&lt;/code&gt;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;              A---B---C my-new-work
             /
D---E---F---G master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Our colleague gives us feedback and we make commit &amp;ldquo;H&amp;rdquo; with some changes. Meanwhile, commits &amp;ldquo;I&amp;rdquo; and &amp;ldquo;J&amp;rdquo; have landed in master.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;              A---B---C---H my-new-work
             /
D---E---F---G---I---J master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can use &lt;code&gt;git rebase master&lt;/code&gt; again to make &amp;ldquo;A&amp;rdquo; slide down the master line. The way this works in reality is that git &amp;ldquo;replays&amp;rdquo; commits &amp;ldquo;A&amp;rdquo;, &amp;ldquo;B&amp;rdquo;, &amp;ldquo;C&amp;rdquo;, and &amp;ldquo;H&amp;rdquo; one at a time as if you had started from &amp;ldquo;J&amp;rdquo;. If at any point a commit conflicts, the &lt;code&gt;git rebase&lt;/code&gt; process will pause and exit. This is to allow you to fix the merge conflict manually. After fixing the conflict you can pickup the rebase where it left off by typing &lt;code&gt;git rebase --continue&lt;/code&gt;. If you decide that that merge conflict is too gnarly you can decide to call the whole thing off with &lt;code&gt;git rebase --abort&lt;/code&gt;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;                      A---B---C---H my-new-work
                     /
D---E---F---G---I---J master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Okay, let&amp;rsquo;s merge to master, creating the merge commit &amp;ldquo;Z&amp;rdquo;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;D---E---F---G---I---J---A---B---C---H---Z master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There you have it, a linear time line of what happened.&lt;/p&gt;
&lt;h2 id=&#34;rewriting-history-with-interactive&#34;&gt;Rewriting history with &lt;code&gt;--interactive&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The majority of my time with rebase is in &lt;code&gt;--interactive&lt;/code&gt; mode. Have you ever gotten done with something and realized you made a simple mistake like a typo? Have you ever then made a commit to fix that typo? Something with the message &amp;ldquo;typo&amp;rdquo; for instance. Then you continue reading and you discover yet another typo, and you make another commit with the message &amp;ldquo;typo&amp;rdquo;. Imagine that the &amp;ldquo;X&amp;rdquo; commits below are those kinds of meaningless commits.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;  A---B---X---X---C---X my-new-work
 /
D master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;An interactive rebase lets you edit, combine, or even drop commits in order to clarify the commit history of your branch. In order to perform an interactive rebase you need a place from which to start it. The commit you choose is the last commit which you want to keep intact and unchanged. In our case above &amp;ldquo;B&amp;rdquo; is a good candidate.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 rebase -i &amp;lt;commit hash/ref of B&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Git will then open up your editor and present you with a plan for how it&amp;rsquo;s going to apply the commits after your chosen commit. Something like:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;pick bbbbbbb some meaningful commit message B
pick deadbee typo
pick fa1afe1 typo
pick ccccccc some meaningful commit message C
pick dabb1ed typo
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This editor session is an opportunity to change the rebase plan by changing the word pick to another verb that rebase understands.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;verb&lt;/th&gt;
          &lt;th&gt;description&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;pick&lt;/td&gt;
          &lt;td&gt;keep this commit in the history&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;edit&lt;/td&gt;
          &lt;td&gt;rebase will stop and let you edit files and commit message&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;break&lt;/td&gt;
          &lt;td&gt;put this on its new line and it will stop like an edit&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;reword&lt;/td&gt;
          &lt;td&gt;change the commit message&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;drop&lt;/td&gt;
          &lt;td&gt;deletes a commit and its changes&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;squash&lt;/td&gt;
          &lt;td&gt;fold commit into the last picked commit, concatenates messages&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;fixup&lt;/td&gt;
          &lt;td&gt;like squash but drops commit messages of the folded commits&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;With this knowledge, here is how I might apply a rebase in our branch scenario above.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;reword bbbbbbb more meaningful info in message B
fixup deadbee typo
fixup fa1afe1 typo
pick ccccccc some meaningful commit message C
fixup dabb1ed typo
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here I reworded the message for commit B, and kept my typo fixes but removed the individual commits and messages for them. When I close the editor session git is going to start applying these changes.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;  A---B---C my-new-work
 /
D master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Voilá! It appears that I never make mistakes and no one can ever prove otherwise!&lt;/p&gt;
&lt;h2 id=&#34;dangerous-and-magical&#34;&gt;Dangerous and magical&lt;/h2&gt;
&lt;p&gt;Seriously, go read the manual. This can be a dangerous process and you can get yourself into a mess if you&amp;rsquo;re not aware of what this command can do. The problems that the manual describes boil down to these:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Someone rebased something you depended on, thus pulling the rug from under you.&lt;/li&gt;
&lt;li&gt;Files got renamed and you didn&amp;rsquo;t account for that.&lt;/li&gt;
&lt;li&gt;Commits, or ranges of commits got dropped during a rebase.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;My generic advice is that you should not rebase branches that you or anyone you are working with has based their work off, and you shouldn&amp;rsquo;t do anything you don&amp;rsquo;t actually understand. Git rebase does some tricky stuff, like detecting duplicate commits and auto resolving them, it can also be used to removes entire range of commits.&lt;/p&gt;
&lt;p&gt;Consider this example from the manual. I&amp;rsquo;ve looked at it a lot and I still don&amp;rsquo;t understand what&amp;rsquo;s happening, but I know that it&amp;rsquo;s dangerous as heck and the implication is that commits disappear.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;E---F---G---H---I---J  topicA
&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 rebase --onto topicA~5 topicA~3 topicA
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Somehow this removes &amp;ldquo;F&amp;rdquo; and &amp;ldquo;G&amp;rdquo;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;E---H&amp;#39;---I&amp;#39;---J&amp;#39;  topicA
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;There is even more to discover about this command. In this blog I covered only what I know and use in my day to day work. I&amp;rsquo;m merely an aspiring time traveler! Thanks for reading this manual review! I hope it has been helpful.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; The good people at &lt;a href=&#34;https://sourcehut.org&#34;&gt;https://sourcehut.org&lt;/a&gt; have put together the pinnacle guide on &lt;code&gt;git-rebase&lt;/code&gt; at &lt;a href=&#34;https://git-rebase.io/&#34;&gt;https://git-rebase.io/&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The git-log manual review</title>
      <link>http://willvaughn.org/articles/the-git-log-manual-review/</link>
      <pubDate>Sat, 05 Oct 2019 21:43:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/the-git-log-manual-review/</guid>
      <description>&lt;p&gt;The &lt;code&gt;git log&lt;/code&gt; command is for exploring the history of a &lt;code&gt;git&lt;/code&gt; repository. You can use it to visualize, search and explore the unique story which has lead to the current state of the code. Personally, the most common ways I&amp;rsquo;ve used &lt;code&gt;git log&lt;/code&gt; are to review my last few commits and to see the commits I&amp;rsquo;ve made since a branch diverged from master.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 log master..HEAD
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is a one-dimensional and basic usage of &lt;code&gt;git log&lt;/code&gt;, and that has been perfectly fine for me. This is, quite frankly, all I have ever needed. Part of my journey though the git manuals is to re-discover familiar commands while looking for new ways to apply them in my workflow. I certainly learned a few things that I will be looking to employ as I see opportunities. I hope you&amp;rsquo;ll learn something from this review as well!&lt;/p&gt;
&lt;h2 id=&#34;basics&#34;&gt;Basics&lt;/h2&gt;
&lt;h3 id=&#34;visualize-the-whole-network-of-changes&#34;&gt;Visualize the whole network of changes&lt;/h3&gt;
&lt;p&gt;The log can all but replace the github network page, or fancy proprietary git GUI tools.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 log --all --graph
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is remarkably good for visualizing the basics of whose doing what, and where. I can imagine in large projects this view could get a bit unwieldy, in which case you&amp;rsquo;ll need to use it with some surgery. In normal size projects this is a good way to quickly get your bearings.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s worth a note that the &lt;code&gt;--decorate&lt;/code&gt; option which shows the full ref names for every commit is enabled by default. Ignoring the reasons for why one would want to turn them off, there is the &lt;code&gt;--no-decorate&lt;/code&gt; option which does allow for turning them off.&lt;/p&gt;
&lt;h3 id=&#34;hide-the-merge-commits-no-merges&#34;&gt;Hide the merge commits &lt;code&gt;--no-merges&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;There are times when seeing how branches have been merged into each other is useful, but much of the time this is just noise. Filter out the noise:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 log --no-merges
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;evolution-of-file--s&#34;&gt;Evolution of file(s)&lt;/h3&gt;
&lt;p&gt;You can easily see a list of commits which affected the given path(s).&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 log ./README.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s a bit trickier when a file has changed locations of course, but &lt;code&gt;git log&lt;/code&gt; has your back with the &lt;code&gt;--follow&lt;/code&gt; option which will follow file movements.&lt;/p&gt;
&lt;h3 id=&#34;tracking-changes-of-line-numbers-or-functions&#34;&gt;Tracking changes of line numbers or functions&lt;/h3&gt;
&lt;p&gt;You want to know how a certain section of a file changed.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;git log -L 1,20:app.py
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Show every commit, and diffs for them, which makes an alteration to the first 20 lines of a python file. Probably going to consist of changes that document every time you made new imports. :)&lt;/p&gt;
&lt;p&gt;You can also look at commits which alter a particular function in a file.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-nil&#34; data-lang=&#34;nil&#34;&gt;git log -L :create_app:app.py
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will show all commits which affected the &lt;code&gt;create_app&lt;/code&gt; function. Extremely useful!&lt;/p&gt;
&lt;h3 id=&#34;basic-output-formatting-pretty&#34;&gt;Basic output formatting &lt;code&gt;--pretty&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The above commands automatically shows the full diffs for each commit, but if you want to see a more concise summary of each commit the commit formatting and diff options of &lt;code&gt;git log&lt;/code&gt; are invaluable.&lt;/p&gt;
&lt;p&gt;You can use &lt;code&gt;-s&lt;/code&gt;, &lt;code&gt;--no-patch&lt;/code&gt; to suppress the diff output entirely.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 log --no-patch -L :create_app:app.py
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To format the commits, the &lt;code&gt;--pretty&lt;/code&gt; options are really convenient. The options in increasingly more verbose order are &lt;code&gt;oneline&lt;/code&gt;, &lt;code&gt;short&lt;/code&gt;, &lt;code&gt;medium&lt;/code&gt;, &lt;code&gt;full&lt;/code&gt;, &lt;code&gt;fuller&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;, &lt;code&gt;raw&lt;/code&gt;. You can also of course set your own formats.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 log --no-patch --pretty=oneline -L :create_app:app.py
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;commit-limiting&#34;&gt;Commit limiting&lt;/h2&gt;
&lt;p&gt;Along with being able to define ranges of commits using normal &lt;strong&gt;gitrevisions&lt;/strong&gt; techniques, the &lt;code&gt;git log&lt;/code&gt; command offers additional ways to further limit the displayed objects.&lt;/p&gt;
&lt;h3 id=&#34;exploring-by-date-with-since-and-until&#34;&gt;Exploring by date with &lt;code&gt;--since&lt;/code&gt; and &lt;code&gt;--until&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Here&amp;rsquo;s one for the overzealous managers out there (not that you would ever read blogs about the git manual): every commit your dev team made in Q1 this year.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 log --since=2019-01-01 --until=2019-04-01 --no-merges
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This shows them in reverse chronological order though, no executive is going to want to look at it like that. So we will flip them&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 log --since=2019-01-01 --until=2019-04-01 --no-merges --reverse
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These options are also available under the aliases &lt;code&gt;--after&lt;/code&gt; and &lt;code&gt;--before&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;exploring-by-author&#34;&gt;Exploring by &lt;code&gt;--author&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;What has she ever done?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 log --author=&lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;Ada Lovelace&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;searching-your-log-messages-grep&#34;&gt;Searching your log messages &lt;code&gt;--grep&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;All the commits which contain the substring &amp;ldquo;separate&amp;rdquo;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 log --grep=separate
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Using some regex, let&amp;rsquo;s see only the ones that start with &amp;ldquo;separate&amp;rdquo;, but let&amp;rsquo;s also throw in the fact that we often don&amp;rsquo;t spell that word correctly.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 log --perl-regexp --regexp-ignore-case --grep=&lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;^sep[ae]rate\s&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I really enjoyed learning more about &lt;code&gt;git log&lt;/code&gt; and I hope that it prompts me to ask more interesting questions of my repositories. All the best! Thanks for reading the manual review!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The gitrevisions manual review</title>
      <link>http://willvaughn.org/articles/the-gitrevisions-manual-review/</link>
      <pubDate>Sat, 14 Sep 2019 15:50:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/the-gitrevisions-manual-review/</guid>
      <description>&lt;h2 id=&#34;review&#34;&gt;Review&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;gitrevisions&lt;/code&gt; manual describes all the ways you can reference objects, and ranges of objects, in &lt;code&gt;git&lt;/code&gt;. If you have used git for a while and are comfortable using it, but don&amp;rsquo;t feel like a master of it; &lt;code&gt;gitrevisions&lt;/code&gt; can and should be your next step. I believe this manual teaches the intermediate git user the language they need for describing the structure of their git repo. The &lt;code&gt;git log --graph&lt;/code&gt; command shows a repository as a graph of objects, blobs(files) and trees(dirs), as it changes over time. It makes sense to me to think of revisions as coordinates in that graph. I enjoyed reading this manual, I hope you will learn something from my review of it.&lt;/p&gt;
&lt;h2 id=&#34;revisions&#34;&gt;Revisions&lt;/h2&gt;
&lt;h3 id=&#34;by-commit-with-sha-1&#34;&gt;By commit with &lt;code&gt;&amp;lt;SHA-1&amp;gt;&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Each commit object has a single unique name within the repository, its SHA-1 hash e.g. &lt;code&gt;0bde21a&lt;/code&gt;, &lt;code&gt;0bde21a835dbb052b00895b69cf6e345a2406ed0&lt;/code&gt;. This hash is the ultimate identity of every revision, and can be used from anywhere. The rest of of the &lt;code&gt;gitrevisions&lt;/code&gt; manual is about ways to target commit objects by names other than their 40-character hash, which would be difficult to work with.&lt;/p&gt;
&lt;h3 id=&#34;named-commits-with-refname&#34;&gt;Named commits with &lt;code&gt;&amp;lt;refname&amp;gt;&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;It&amp;rsquo;s difficult to go far in git without using refnames. These are things like &lt;code&gt;HEAD&lt;/code&gt;, &lt;code&gt;master&lt;/code&gt;, or &lt;code&gt;origin/master&lt;/code&gt;. Behind the scenes git treats these as aliases for refnames like &lt;code&gt;ref/heads/master&lt;/code&gt;, &lt;code&gt;ref/remotes/origin/master&lt;/code&gt;. Curious about these reference names, checkout the contents of your &lt;code&gt;.git/refs&lt;/code&gt; directory.&lt;/p&gt;
&lt;p&gt;There are these other special HEAD refnames which stay consistent in their meaning, even as you change or alter the state of your repository.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;VARIANT&lt;/th&gt;
          &lt;th&gt;DESCRIPTION&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;@&lt;/td&gt;
          &lt;td&gt;An alias for HEAD, when used on its own.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;HEAD&lt;/td&gt;
          &lt;td&gt;commit on which you based changes in the working tree&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;FETCH_HEAD&lt;/td&gt;
          &lt;td&gt;head of last fetched branch using &lt;code&gt;git fetch&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;ORIG_HEAD&lt;/td&gt;
          &lt;td&gt;created internally by git when git is doing an operation that moves HEAD in a drastic way&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;MERGE_HEAD&lt;/td&gt;
          &lt;td&gt;commit which you into your branch with &lt;code&gt;git merge&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;CHERRY_PICK_HEAD&lt;/td&gt;
          &lt;td&gt;commit you are cherry picking when you run &lt;code&gt;git cherry-pick&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;parent-selection-with-rev-n&#34;&gt;Parent selection with &lt;code&gt;&amp;lt;rev&amp;gt;^[&amp;lt;n&amp;gt;]&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;HEAD^&lt;/code&gt; is the first parent of &lt;code&gt;HEAD&lt;/code&gt;. Some commits, such as merge commits, have multiple parents. Using &lt;code&gt;^1&lt;/code&gt; will select the first, and &lt;code&gt;^2&lt;/code&gt; will select the second. What helps me is to think of &lt;code&gt;^1&lt;/code&gt; as a name for &amp;ldquo;Mom&amp;rdquo; and &lt;code&gt;^2&lt;/code&gt; as a name for &amp;ldquo;Dad&amp;rdquo;, and the way you express maternal-Grandma would &lt;code&gt;^1^1&lt;/code&gt;, parent 1 (Mom) of parent 1 (Mom). Similarly maternal Grandpa would be &lt;code&gt;^1^2&lt;/code&gt;. Maybe that&amp;rsquo;s a strange example but I hope it helps with understanding how the caret works in these revisions.&lt;/p&gt;
&lt;h3 id=&#34;generational-ancestors-with-rev-n&#34;&gt;Generational ancestors with &lt;code&gt;&amp;lt;rev&amp;gt;~[&amp;lt;n&amp;gt;]&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;HEAD~3&lt;/code&gt; means go back three ancestors, and is equivalent to &lt;code&gt;HEAD^^^&lt;/code&gt; or &lt;code&gt;HEAD^1^1^1&lt;/code&gt;. I find this is often a more intuitive way of targeting commits in the past than the &lt;code&gt;^&lt;/code&gt; approach.&lt;/p&gt;
&lt;h3 id=&#34;ranges&#34;&gt;ranges&lt;/h3&gt;
&lt;p&gt;Commands like &lt;code&gt;git log&lt;/code&gt; operate on a set of commits. When you enter a single commit to git log you&amp;rsquo;re telling it to show you the commit itself as well as any commits in its ancestry chain. Defining ranges of commits can be used to narrow and focus the information in these commands.&lt;/p&gt;
&lt;h4 id=&#34;exclusion&#34;&gt;Exclusion&lt;/h4&gt;
&lt;p&gt;The first, most basic way to narrow a range is to specify a prefix caret, as in &lt;code&gt;^master&lt;/code&gt;. This means don&amp;rsquo;t show me anything which is an ancestor of master.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 log ^master HEAD
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Shows the commits of your checked out branch since you diverged from master.&lt;/p&gt;
&lt;h4 id=&#34;dotted-ranges&#34;&gt;Dotted Ranges&lt;/h4&gt;
&lt;p&gt;The &lt;code&gt;..&lt;/code&gt; (two-dot) range is an alternative way of excluding commit ancestors. Running &lt;code&gt;git log master..HEAD&lt;/code&gt; is the same as the example above using &lt;code&gt;^master HEAD&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;...&lt;/code&gt; (three-dot) range defines a set of commits that are reachable from either, but not both of the commits.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 log master...HEAD
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Shows what has happened on master since we diverged from it AND what happened on HEAD since we diverged from master. This is useful for showing two separate branches of changes I think.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;origin&lt;/code&gt; is implicitly inserted if you leave off one of the commits on either side of the range.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Simple&lt;/th&gt;
          &lt;th&gt;Implied&lt;/th&gt;
          &lt;th&gt;Meaning&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;..HEAD&lt;/td&gt;
          &lt;td&gt;origin..HEAD&lt;/td&gt;
          &lt;td&gt;What did I do since I diverged from the origin branch?&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;HEAD..&lt;/td&gt;
          &lt;td&gt;HEAD..origin&lt;/td&gt;
          &lt;td&gt;What does the origin branch have that I don&amp;rsquo;t have since I diverged from it&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;history-by-date-with-refname-date&#34;&gt;History by date with &lt;code&gt;&amp;lt;refname&amp;gt;@{&amp;lt;date&amp;gt;}&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;This tries to get the exact commit for that reference as it was at the specified time. For example:&lt;/p&gt;
&lt;p&gt;What was in my local master branch 1 week ago?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 show &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;master@{1 week ago}&amp;#39;&lt;/span&gt;=
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;shortcut-to-the-upstream-branch-with-branchname-upstream&#34;&gt;Shortcut to the upstream branch with &lt;code&gt;&amp;lt;branchname&amp;gt;@{upstream}&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Using &lt;code&gt;@{upstream}&lt;/code&gt; will reference the commit of the branch configured by &lt;code&gt;branch.&amp;lt;name&amp;gt;.remote&lt;/code&gt; and &lt;code&gt;branch.&amp;lt;name&amp;gt;.merge&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&#34;shortcut-to-the-push-branch-with-branchname-push&#34;&gt;Shortcut to the push branch with &lt;code&gt;&amp;lt;branchname&amp;gt;@{push}&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Using &lt;code&gt;@{push}&lt;/code&gt; will reference the commit of the branch configured by &lt;code&gt;push.default&lt;/code&gt;. The manual describes this as a reference to &amp;ldquo;where we would push to if &lt;code&gt;git push&lt;/code&gt; were run while &lt;code&gt;branchname&lt;/code&gt; was checked out.&lt;/p&gt;
&lt;h3 id=&#34;refer-to-a-file-or-subtree-of-a-revision-with-rev-path&#34;&gt;Refer to a file or subtree of a revision with &lt;code&gt;&amp;lt;rev&amp;gt;:&amp;lt;path&amp;gt;&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Targets files or a directory at the given path. For instance:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 show origin/master:README.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;OR&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 diff origin/master:blog.org
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To show the difference between the blog.org file in the working tree, and the one on origin/master. That first argument &lt;code&gt;origin/master&lt;/code&gt; is a revision. Git diff can take a path revision to show a diff between blog.org in my working tree, and the repositories README.md on origin. Why do this? I have no idea, but it works!&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 diff origin/master:./README.md blog.org=
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, throwing it all together! What&amp;rsquo;s the diff between origin master blog.org, and origin master blog.org from 1 week ago?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 diff origin/master:blog.org &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;origin/master@{1 week ago}:blog.org&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;After reading and reviewing this manual, I am planning to commands which leverage the power of revisions like &lt;code&gt;git-log&lt;/code&gt;, &lt;code&gt;git-rebase&lt;/code&gt;, and &lt;code&gt;git-push&lt;/code&gt;. I think I&amp;rsquo;ll be coming back to this document pretty often as I dig into these other tools. As always, thank you so much for reading this manual review!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The giteveryday manual review</title>
      <link>http://willvaughn.org/articles/the-giteveryday-manual-review/</link>
      <pubDate>Sun, 08 Sep 2019 17:09:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/the-giteveryday-manual-review/</guid>
      <description>&lt;p&gt;The &lt;code&gt;giteveryday(7)&lt;/code&gt; manual seeks to describe a minimal set of useful commands for everyday usage of git.&lt;/p&gt;
&lt;p&gt;There really isn&amp;rsquo;t much of a reason to read this manual. I actually found it rather interesting, but only from an archaeology of software development point of view. It feels a bit outdated for a beginning programmer. It describes ways to email patches to developers, and apply patches from emails, as well as how to spin up a git daemon or a git web front-end. I recommend scanning this manual quickly for the example commands that are being described and only reading more if something catches your interest.&lt;/p&gt;
&lt;p&gt;Thanks for reading this manual review!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The gittutorial manual review</title>
      <link>http://willvaughn.org/articles/the-gittutorial-manual-review/</link>
      <pubDate>Mon, 02 Sep 2019 22:28:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/the-gittutorial-manual-review/</guid>
      <description>&lt;p&gt;The git tutorial manual is actually two separate manuals, &lt;code&gt;gittutorial(7)&lt;/code&gt; and &lt;code&gt;gittutorial-2(7)&lt;/code&gt;. I will be reviewing them both in this post, followed by some brief summaries of what I learned or thought was noteworthy while reading them.&lt;/p&gt;
&lt;h2 id=&#34;review&#34;&gt;Review&lt;/h2&gt;
&lt;p&gt;I think if I were an absolute beginner and I started with these tutorials, the &lt;code&gt;gittutorial&lt;/code&gt; would be slightly helpful, and the &lt;code&gt;gittutorial-2&lt;/code&gt; would be confusing. I don&amp;rsquo;t think the manual is where true beginners typically start with git. I would guess many learn the basics of git as part of the learning the basics of programming. The &lt;code&gt;gittutorial&lt;/code&gt; manual is a reiteration of the basics. It gives enough context on git to start using it, though I wouldn&amp;rsquo;t say it does so particularly well. There are probably better and more practical getting started tutorials available from a quick google search. This manual feels outdated because the examples are of Alice and Bob sharing a single filesystem where they both have user directories and their own repositories. That&amp;rsquo;s not typically how we work with git these days, and I don&amp;rsquo;t think it&amp;rsquo;s a helpful distraction for todays beginner programmer.&lt;/p&gt;
&lt;p&gt;In contrast, the &lt;code&gt;gittutorial-2&lt;/code&gt; manual quickly gets you straight into the internal architecture of git in a way that could be overwhelming for a beginner. As a developer who has been using git for 10 years without ever reading the manual though, this was illuminating! This felt like information I had been missing. While it may be overwhelming for a beginner perhaps it is best to be forced to go a little deeper in order to build a foundational and lasting understanding. I think I would recommend a beginner to read &lt;code&gt;gittutorial-2&lt;/code&gt; in their first few months of learning, but not right away. This manual aims to teach how to think about a git repository as a system and database of information. I think that vantage can potentially be a leg-up in learning to wield git beyond the basics.&lt;/p&gt;
&lt;h2 id=&#34;gittutorial&#34;&gt;gittutorial&lt;/h2&gt;
&lt;p&gt;Some things I learned and plan to use.&lt;/p&gt;
&lt;h3 id=&#34;log-and-dot-dot-ranges&#34;&gt;log and .. ranges&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 log --stat --summary
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is a nice view on the log.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 fetch /home/bob/myrepo master
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git log -p HEAD..FETCH_HEAD
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The usage of &lt;code&gt;git fetch&lt;/code&gt; and the &lt;code&gt;FETCH_HEAD&lt;/code&gt; symbol as a way to peek at code. This also demonstrates the concept of commit ranges, which I rarely use and probably could use more.&lt;/p&gt;
&lt;p&gt;The two-dot &lt;code&gt;..&lt;/code&gt; form means: show everything that is reachable from FETCH_HEAD, but exclude anything that is reachable from HEAD. The example in the manual is a peek at Bob&amp;rsquo;s changes absent of Alice&amp;rsquo;s changes.&lt;/p&gt;
&lt;p&gt;The three-dot &lt;code&gt;...&lt;/code&gt; form means: show everything that is reachable from either, but exclude anything that is reachable from both. This is a view of Alice&amp;rsquo;s changes combined with Bob&amp;rsquo;s changes.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 log --since=&lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;2 weeks ago&amp;#34;&lt;/span&gt; &lt;span style=&#34;font-style:italic&#34;&gt;# commits from the last 2 week&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Could be handy occasionally.&lt;/p&gt;
&lt;h3 id=&#34;gitk&#34;&gt;gitk&lt;/h3&gt;
&lt;p&gt;I didn&amp;rsquo;t know this existed. Its a Tkinter based UI for git! It&amp;rsquo;s pretty old-school cool. I&amp;rsquo;m happy that it exists and I&amp;rsquo;m going to find reasons to open it up in strange situations when pairing with colleagues, just to see their reactions.&lt;/p&gt;
&lt;h3 id=&#34;git-show&#34;&gt;git show&lt;/h3&gt;
&lt;p&gt;An introduction to seeing the details of commits. I think I often go straight to github when I need to find a commit, when it may be much easier to use &lt;code&gt;git show&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Git ancestry targeting:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;HEAD^&lt;/code&gt;, &lt;code&gt;HEAD^1&lt;/code&gt; is the parent of HEAD&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HEAD^^&lt;/code&gt;, &lt;code&gt;HEAD^2&lt;/code&gt; is the grandparent of HEAD&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HEAD^4&lt;/code&gt; is the great-great grandparent of HEAD&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;git-grep&#34;&gt;git grep&lt;/h3&gt;
&lt;p&gt;Search a commit for a pattern. I did not know this existed.&lt;/p&gt;
&lt;h2 id=&#34;gittutorial-2&#34;&gt;gittutorial-2&lt;/h2&gt;
&lt;h3 id=&#34;objects&#34;&gt;Objects&lt;/h3&gt;
&lt;p&gt;Git &amp;ldquo;commit&amp;rdquo; objects refer to snapshots of the whole directory structure in a repo known as a &amp;ldquo;tree&amp;rdquo;. Each directory is a tree object in git, and file data is stored in &amp;ldquo;blobs&amp;rdquo;. The trees can themselves refer to other trees (sub directories). Using &lt;code&gt;git cat-file&lt;/code&gt; and &lt;code&gt;git ls-tree&lt;/code&gt; you can introspect the objects stored by git.&lt;/p&gt;
&lt;h3 id=&#34;the-index-file&#34;&gt;The index file&lt;/h3&gt;
&lt;p&gt;The index let&amp;rsquo;s git show us the difference between the state of the working directory and the last commit. By default git uses the index to create commits, not the working directory. What I learned here, which I already knew by using git was I can use &lt;code&gt;git add&lt;/code&gt; to manipulate the index in order to shape commits, without necessarily discarding my working tree. In practice I don&amp;rsquo;t really do this often, I just add everything to a commit.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;gittutorial-2&lt;/code&gt; is worth a look, you&amp;rsquo;ll learn about how git works in a way which should help you master it. There&amp;rsquo;s still a lot more for me to read about git. My plan is to move on to the &lt;code&gt;giteveryday&lt;/code&gt; manual. I&amp;rsquo;ve also been trying to work my way through the &lt;a href=&#34;https://git.github.io/htmldocs/user-manual.html&#34;&gt;Git User&amp;rsquo;s Manual&lt;/a&gt;, as well as the manual for &lt;a href=&#34;https://magit.vc/manual/magit.html&#34;&gt;Magit&lt;/a&gt;; a great interface to git from within Emacs. It doesn&amp;rsquo;t shield you from git, but like &lt;code&gt;gitk&lt;/code&gt;, it gives you a different way to visualize and manipulate the database of git objects.&lt;/p&gt;
&lt;p&gt;Go RTFM! And as always, thanks for reading the manual review!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The git manual review</title>
      <link>http://willvaughn.org/articles/the-git-manual-review/</link>
      <pubDate>Mon, 02 Sep 2019 21:04:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/the-git-manual-review/</guid>
      <description>&lt;p&gt;Running &lt;code&gt;man git&lt;/code&gt; opens up the entrypoint on git documentation, there are separate manuals for every command, references to the &lt;a href=&#34;https://git.github.io/htmldocs/user-manual.html&#34;&gt;Git User&amp;rsquo;s Manual&lt;/a&gt; and the &lt;code&gt;gittutorial&lt;/code&gt;, as well as &lt;code&gt;giteveryday&lt;/code&gt;. I&amp;rsquo;m not going to be able to do a single write-up on all this information, it&amp;rsquo;s going to take me like a year to read it all! So I think what I&amp;rsquo;ll do with my &lt;code&gt;git&lt;/code&gt; review is spread it out over multiple blogs a little bit at a time. I&amp;rsquo;ll start with &lt;code&gt;gittutorial(7)&lt;/code&gt; soon.&lt;/p&gt;
&lt;p&gt;As I read and review git manuals, I will post links to them from here. This is now the table of contents for my &lt;code&gt;git&lt;/code&gt; manual reviews.&lt;/p&gt;
&lt;p&gt;Remember to RTFM. Thanks for reading!&lt;/p&gt;
&lt;p&gt;Reviews:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://willvaughn.org/articles/the-gittutorial-manual-review&#34;&gt;gittutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://willvaughn.org/articles/the-giteveryday-manual-review&#34;&gt;giteveryday&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://willvaughn.org/articles/the-gitrevisions-manual-review&#34;&gt;gitrevisions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://willvaughn.org/articles/the-git-log-manual-review&#34;&gt;git-log&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://willvaughn.org/articles/the-git-rebase-manual-review&#34;&gt;git-rebase&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://willvaughn.org/articles/the-git-diff-manual-review&#34;&gt;git-diff&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://willvaughn.org/articles/the-git-add-manual-review&#34;&gt;git-add&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>The curl manual review</title>
      <link>http://willvaughn.org/articles/the_curl_manual_review/</link>
      <pubDate>Mon, 19 Aug 2019 23:22:00 -0700</pubDate>
      
      <guid>http://willvaughn.org/articles/the_curl_manual_review/</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#basic-curl&#34;&gt;Basic curl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#essential-curl&#34;&gt;Essential curl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#you-don-t-know-curl&#34;&gt;You don&amp;rsquo;t know curl&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;review&#34;&gt;Review&lt;/h2&gt;
&lt;p&gt;I can now recommend the &lt;code&gt;curl&lt;/code&gt; manual. It was definitely worth the read. I discovered things about &lt;code&gt;curl&lt;/code&gt; that I didn&amp;rsquo;t know before and a great deal about how to more effectively use it. The manual contains a lot of information about niche topics like socks, proxies, and FTP servers. Most of which I skimmed. I tried to concentrate on aspects of &lt;code&gt;curl&lt;/code&gt; I thought I would use often.&lt;/p&gt;
&lt;p&gt;I chose to read it because I wanted to better understand the capabilities of &lt;code&gt;curl&lt;/code&gt; and to recognize common spots where employing it could save me time and effort. I found the URL syntax documentation especially informative.&lt;/p&gt;
&lt;p&gt;Because I work for a company focused on the climate, many of the examples below involve this index of global hourly NOAA weather data. It is organized by years, and USAF and WBAN station ids. Referring to the structure of this directory may help you better understand the examples below.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.ncei.noaa.gov/data/global-hourly/&#34;&gt;https://www.ncei.noaa.gov/data/global-hourly/&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;basic-curl&#34;&gt;Basic &lt;code&gt;curl&lt;/code&gt;&lt;/h2&gt;
&lt;h3 id=&#34;output-content-to-stdout&#34;&gt;Output content to stdout&lt;/h3&gt;
&lt;p&gt;The station id for SFO (San Francisco International Airport) is 72494023234. This request prints the csv data to stdout.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 https://www.ncei.noaa.gov/data/global-hourly/access/2016/72494023234.csv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Using grep on the output to view data for a particular day.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;  https://www.ncei.noaa.gov/data/global-hourly/access/2016/72494023234.csv &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;  | grep &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;2016-07-28&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;downloading-files-with-o-output-and-o-remote-name&#34;&gt;Downloading files with &lt;code&gt;-o&lt;/code&gt;, &lt;code&gt;--output&lt;/code&gt; and &lt;code&gt;-O&lt;/code&gt;, &lt;code&gt;--remote-name&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Downloading the SFO data.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 scratch/2016/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;  https://www.ncei.noaa.gov/data/global-hourly/access/2016/72494023234.csv &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;  --output scratch/2016/sf-weather.csv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Using the alias &lt;code&gt;-o&lt;/code&gt; instead.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;  https://www.ncei.noaa.gov/data/global-hourly/access/2016/72494023234.csv &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;  -o scratch/2016/sf-weather.csv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;using-a-progress-bar-with-progress-bar&#34;&gt;Using a progress bar with &lt;code&gt;-#&lt;/code&gt;, &lt;code&gt;--progress-bar&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;curl&lt;/code&gt; will display a progress meter with the amount of transferred information and how long the request took.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                 Dload  Upload   Total   Spent    Left  Speed
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;100 6825k  100 6825k    0     0  1988k      0  0:00:03  0:00:03 --:--:-- 1988k
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Providing &lt;code&gt;-#&lt;/code&gt; or &lt;code&gt;--progress-bar&lt;/code&gt; arguments will display a progress bar of the transfer instead.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  https://www.ncei.noaa.gov/data/global-hourly/access/2016/72494023234.csv \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -o scratch/2016/sf-weather.csv \
&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;############################################################################### 100.0%
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you don&amp;rsquo;t want any progress meter, use &lt;code&gt;-s&lt;/code&gt;, &lt;code&gt;--silent&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;api-requests-with-request-data-and-header&#34;&gt;API requests with &lt;code&gt;--request&lt;/code&gt;, &lt;code&gt;--data&lt;/code&gt;, and &lt;code&gt;--header&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The NOAA website doesn&amp;rsquo;t provide any use for POST requests, so consider a micro-blogging API which is completely made up. ;-)&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    -X POST &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    --url &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;https://api.microblog.com/1.1/statuses/update.json&amp;#39;&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    -d &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;{&amp;#34;status&amp;#34;: &amp;#34;hello&amp;#34;}&amp;#39;&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    -H &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;Content-Type: application/json&amp;#39;&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    -H &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;authorization: OAuth ...oauth info...&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Args in this request:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-X&lt;/code&gt;, &lt;code&gt;--request&lt;/code&gt; argument varies the HTTP verb of the request.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--url&lt;/code&gt; is the ordinary positional URL argument as a named argument.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-d&lt;/code&gt;, &lt;code&gt;--data&lt;/code&gt; is the data to post. In this case a JSON document.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-H&lt;/code&gt;, &lt;code&gt;--header&lt;/code&gt; supplies HTTP Headers to the post.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To post data contained in a file, use the &lt;code&gt;@&lt;/code&gt; symbol with the &lt;code&gt;--data&lt;/code&gt; arg:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;--data @path/to/big_data_file.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;making-head-requests-with-i-head&#34;&gt;Making HEAD requests with &lt;code&gt;-I&lt;/code&gt;, &lt;code&gt;--head&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Retrieve only the header of a document. Useful when the content of a request is not consequential. I use this sometimes as a simple test of network connectivity to a server, or to see the raw 301 response before a redirected request.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;  -I &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;  https://www.ncei.noaa.gov/data/global-hourly/access/2016/72494023234.csv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Produces:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HTTP/1.1 200 OK
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Date: Mon, 26 Aug 2019 04:37:49 GMT
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Server: Apache
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Strict-Transport-Security: max-age=31536000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Last-Modified: Wed, 19 Dec 2018 17:25:32 GMT
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ETag: &amp;#34;ae57fe0-6aa4e2-57d634d14db00&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Accept-Ranges: bytes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Content-Length: 6989026
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Content-Type: text/csv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Access-Control-Allow-Origin: *
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Access-Control-Allow-Headers: X-Requested-With, Content-Type
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Connection: close
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;following-redirects-with-l-location&#34;&gt;Following redirects with &lt;code&gt;-L&lt;/code&gt;, &lt;code&gt;--location&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Web pages can be tricky, hitting one might move you to another. Consider the following request to &lt;a href=&#34;https://google.com&#34;&gt;https://google.com&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 https://google.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;font-weight:bold&#34;&gt;HTML&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;font-weight:bold&#34;&gt;HEAD&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;font-weight:bold&#34;&gt;meta&lt;/span&gt; http-equiv=&lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;content-type&amp;#34;&lt;/span&gt; content=&lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;text/html;charset=utf-8&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;font-weight:bold&#34;&gt;TITLE&lt;/span&gt;&amp;gt;301 Moved&amp;lt;/&lt;span style=&#34;font-weight:bold&#34;&gt;TITLE&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;font-weight:bold&#34;&gt;HEAD&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;font-weight:bold&#34;&gt;BODY&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;font-weight:bold&#34;&gt;H1&lt;/span&gt;&amp;gt;301 Moved&amp;lt;/&lt;span style=&#34;font-weight:bold&#34;&gt;H1&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;The document has moved
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;font-weight:bold&#34;&gt;A&lt;/span&gt; HREF=&lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;https://www.google.com/&amp;#34;&lt;/span&gt;&amp;gt;here&amp;lt;/&lt;span style=&#34;font-weight:bold&#34;&gt;A&lt;/span&gt;&amp;gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;font-weight:bold&#34;&gt;BODY&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;font-weight:bold&#34;&gt;HTML&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This doesn&amp;rsquo;t produce the full google web page; it is a redirect to the full google experience. Looking into the response headers we can see the details of this redirect.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 -I https://google.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HTTP/2 301
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;location: https://www.google.com/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;content-type: text/html; charset=UTF-8
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;date: Mon, 26 Aug 2019 04:46:00 GMT
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;expires: Wed, 25 Sep 2019 04:46:00 GMT
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cache-control: public, max-age=2592000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;server: gws
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;content-length: 220
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;x-xss-protection: 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;x-frame-options: SAMEORIGIN
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;alt-svc: quic=&amp;#34;:443&amp;#34;; ma=2592000; v=&amp;#34;46,43,39&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;By default &lt;code&gt;curl&lt;/code&gt; isn&amp;rsquo;t following this redirect to the google home page in the same way your web browser does. The &lt;code&gt;-L&lt;/code&gt;, &lt;code&gt;--location&lt;/code&gt; argument makes the request follow any redirects through to the final destination.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 -L https://google.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The response here is a much more complicated HTML page for the google website.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 -I -L https://google.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will show the header responses for both the redirect and the final destination.&lt;/p&gt;
&lt;h2 id=&#34;essential-curl&#34;&gt;Essential &lt;code&gt;curl&lt;/code&gt;&lt;/h2&gt;
&lt;h3 id=&#34;downloading-files-with-remote-information-dot&#34;&gt;Downloading files with remote information.&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;-O&lt;/code&gt;, &lt;code&gt;--remote-name&lt;/code&gt; option lets us use file names from the server. Similarly, &lt;code&gt;-R&lt;/code&gt;, &lt;code&gt;--remote-time&lt;/code&gt; attempts to use the servers timestamp of the file if it is available.&lt;/p&gt;
&lt;p&gt;Uses the remote name of the file and saves the file to the current working directory.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 -OR https://www.ncei.noaa.gov/data/global-hourly/access/2016/72494023234.csv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The file is downloaded to &lt;code&gt;./72494023234.csv&lt;/code&gt;, and &lt;code&gt;ls -l&lt;/code&gt; reveals that even though I am downloading this data in 2019, the last modified time of this file was in 2018.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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;-rw-r--r--  1 nackjicholson  staff  6989026 Dec 19  2018 72494023234.csv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;storing-request-header-information-with-d-dump-header&#34;&gt;Storing request header information with &lt;code&gt;-D&lt;/code&gt;, &lt;code&gt;--dump-header&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Sometimes when inspecting requests or API responses, you may want to dump header information along with the request.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 -OR &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;  -D headers.txt &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;  https://www.ncei.noaa.gov/data/global-hourly/access/2016/72494023234.csv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;sending-form-data-with-f-form&#34;&gt;Sending form data with &lt;code&gt;-F&lt;/code&gt;, &lt;code&gt;--form&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Just do &lt;code&gt;man curl&lt;/code&gt; and search for &lt;code&gt;--form&lt;/code&gt;, and read about it. It&amp;rsquo;s going to be more informative than anything I can say here.&lt;/p&gt;
&lt;p&gt;Features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Send files with &lt;code&gt;@&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Send input fields&lt;/li&gt;
&lt;li&gt;Specify content types per field&lt;/li&gt;
&lt;li&gt;Load content from text fields with &lt;code&gt;&amp;lt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;ignore-ssl-with-insecure&#34;&gt;Ignore SSL with &lt;code&gt;--insecure&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;When hitting routes which require SSL &lt;code&gt;curl&lt;/code&gt; will fail.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxx.us-west-2.elb.amazonaws.com&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl: (51) SSL: no alternative certificate subject name matches target host name &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxx.us-west-2.elb.amazonaws.com&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I encounter this occassionally trying to connect to an AWS load balancer before associating them with a DNS name and a valid SSL cert.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 --insecure &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxx.us-west-2.elb.amazonaws.com&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;you-don-t-know-curl&#34;&gt;You don&amp;rsquo;t know &lt;code&gt;curl&lt;/code&gt;&lt;/h2&gt;
&lt;h3 id=&#34;sending-multiple-requests-using-url-syntax&#34;&gt;Sending multiple requests using URL Syntax&lt;/h3&gt;
&lt;p&gt;The url sent to &lt;code&gt;curl&lt;/code&gt; can be given multiple values to create multiple requests. Using syntax &lt;code&gt;{foo,bar}&lt;/code&gt; brackets creates sets which replace parts of a URL. For example, we can request data for the New York La Guardia Airport (72503014732) and San Francisco International Airport (72494023234) in a single request.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;https://www.ncei.noaa.gov/data/global-hourly/access/2016/{7294023234,72503014732}.csv&amp;#39;&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    -o scratch/sf-weather.csv &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    -o scratch/ny-weather.csv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Using two &lt;code&gt;-o&lt;/code&gt; arguments writes two output files, one for each request, in the order they are defined. We can also use &lt;code&gt;[..]&lt;/code&gt; to create ranges of values. The NOAA data is organized into directories by year. We can create a URL that will get us the SFO and LGA data for a sequence of years. We could then use as many &lt;code&gt;--output&lt;/code&gt; arguments as necessary to write all the files out, but there is an easier way by templating the &lt;code&gt;--output&lt;/code&gt; names as well.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;https://www.ncei.noaa.gov/data/global-hourly/access/[2012-2019]/{7294023234,72 503014732}.csv&amp;#39;&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    --create-dirs &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    --progress-bar &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;    --output &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;scratch/#1/#2-weather.csv&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will download 16 files for SFO and LGA, creating a directory structure using &lt;code&gt;--create-dirs&lt;/code&gt; and the names &lt;code&gt;#1&lt;/code&gt; and &lt;code&gt;#2&lt;/code&gt; which correspond respectively to the two substitution parts of our URL in the order they are defined. The first is the range of years, and the second is the set of station ids.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;scratch
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── 2012
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   ├── 72503014732-weather.csv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   └── 7294023234-weather.csv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── 2013
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   ├── 72503014732-weather.csv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   └── 7294023234-weather.csv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── 2014
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   ├── 72503014732-weather.csv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   └── 7294023234-weather.csv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── 2015
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   ├── 72503014732-weather.csv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   └── 7294023234-weather.csv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── 2016
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   ├── 72503014732-weather.csv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   └── 7294023234-weather.csv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── 2017
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   ├── 72503014732-weather.csv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   └── 7294023234-weather.csv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── 2018
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   ├── 72503014732-weather.csv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   └── 7294023234-weather.csv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;└── 2019
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── 72503014732-weather.csv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    └── 7294023234-weather.csv
&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;8 directories, 16 files
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;saving-request-configurations-with-k-config&#34;&gt;Saving request configurations with &lt;code&gt;-K&lt;/code&gt;, &lt;code&gt;--config&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;When requests start getting large, difficult to remember, or tedious to type; you can use the &lt;code&gt;--config&lt;/code&gt; feature of &lt;code&gt;curl&lt;/code&gt; to save the request options to a file.&lt;/p&gt;
&lt;p&gt;This saves our complicated configuration.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;bulk_station_download.txt&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;url = &amp;#34;https://www.ncei.noaa.gov/data/global-hourly/access/[2012-2019]/{7294023234,72503014732}.csv&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;output = &amp;#34;scratch/#1/#2-weather.csv&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--create-dirs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--progress-bar
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we can perform this request using:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 -K bulk_station_download.txt
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;separate-requests-with-next&#34;&gt;Separate Requests with &lt;code&gt;-:&lt;/code&gt;, &lt;code&gt;--next&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;This will let you chain posts in order. A sample use for this might be to do a POST creating a resource, and then follow it with GET to make sure it&amp;rsquo;s accessible.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;  -X POST &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;  -H &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#39;Content-Type: application/json&amp;#39;&lt;/span&gt; &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;  -d @my_thing.json &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;  http://api.example.com/things &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;  -: &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;  http://api.example.com/things/my_thing &lt;span style=&#34;font-weight:bold;font-style:italic&#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;font-weight:bold;font-style:italic&#34;&gt;&lt;/span&gt;  -o my_thing.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;writing-out-request-information-and-statistics-with-w-write-out&#34;&gt;Writing out request information and statistics with &lt;code&gt;-w&lt;/code&gt;, &lt;code&gt;--write-out&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;This &lt;a href=&#34;https://stackoverflow.com/questions/18215389/how-do-i-measure-request-and-response-times-at-once-using-curl&#34;&gt;StackOverflow&lt;/a&gt; has great information about how to do this, and the &lt;code&gt;curl&lt;/code&gt; manual has a list of the templating variables you can use in your &lt;code&gt;-w&lt;/code&gt; template files.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;curl_request_info.txt&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   time_namelookup:  %{time_namelookup}\n
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      time_connect:  %{time_connect}\n
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   time_appconnect:  %{time_appconnect}\n
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  time_pretransfer:  %{time_pretransfer}\n
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     time_redirect:  %{time_redirect}\n
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;time_starttransfer:  %{time_starttransfer}\n
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   ----------\n
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        time_total:  %{time_total}\n
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then make a request. This one doesn&amp;rsquo;t even download the file, it just pipes it&amp;rsquo;s content to &lt;code&gt;/dev/null&lt;/code&gt; and shows the stats.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-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 -w &lt;span style=&#34;font-style:italic&#34;&gt;&amp;#34;@curl_request_info.txt&amp;#34;&lt;/span&gt; -s -o /dev/null https://www.ncei.noaa.gov/data/global-hourly/access/2016/72494023234.csv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And you&amp;rsquo;ll get back something like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   time_namelookup:  0.001
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      time_connect:  0.037
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   time_appconnect:  0.000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  time_pretransfer:  0.037
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     time_redirect:  0.000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;time_starttransfer:  0.092
&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;        time_total:  0.164
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;There were a few other things I thought looked cool, but didn&amp;rsquo;t play with.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Abort slow downloads &lt;code&gt;-Y&lt;/code&gt;, &lt;code&gt;--speed-limit&lt;/code&gt; in bytes per seconds&lt;/li&gt;
&lt;li&gt;Abort slow downloads after a given time &lt;code&gt;-y&lt;/code&gt;, &lt;code&gt;--speed-time&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Retries with &lt;code&gt;--retry&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Remember to RTFM! Thanks for reading my review.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>William Vaughn - San Francisco, CA</title>
      <link>http://willvaughn.org/resume/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>http://willvaughn.org/resume/</guid>
      <description>&lt;p&gt;Software Engineering Leader - &lt;a href=&#34;mailto:will@willvaughn.org&#34;&gt;will@willvaughn.org&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;objective&#34;&gt;Objective&lt;/h2&gt;
&lt;p&gt;To build, architect, and operate data-centric software applications. To create productive software environments that challenge, teach, grow, and support professional crafts-persons.&lt;/p&gt;
&lt;h2 id=&#34;employment&#34;&gt;Employment&lt;/h2&gt;
&lt;div class=&#34;tiled&#34;&gt;
&lt;div class=&#34;tile full&#34;&gt;
&lt;h3 id=&#34;carbon-lighthouse-san-francisco-ca&#34;&gt;&lt;a href=&#34;https://www.carbonlighthouse.com/&#34;&gt;Carbon Lighthouse&lt;/a&gt; - San Francisco, CA&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;2016-Present &amp;ndash; Principal SWE &amp;lt; VP of Software &amp;lt; SWE Manager &amp;lt; Lead SWE &amp;lt; Sr. SWE&lt;/strong&gt;&lt;br /&gt;
Company founded to stop climate change through profitable decarbonization of commercial real estate.&lt;br /&gt;
I started as an individual contributor, and progressed to organizational leader overseeing a cross-functional team building energy modeling applications on AWS, Kubernetes, and Python.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Designed and built data ingest system, foundational to collecting and analyzing hundreds of millions of timeseries points from building sensors.&lt;/li&gt;
&lt;li&gt;Led company&amp;rsquo;s data-driven transition by implementing and evangelizing a modern data and reporting stack on Snowflake, Fivetran, and dbt.&lt;/li&gt;
&lt;li&gt;Reduced operational overhead by leading migration from Apache HBASE to AWS DynamoDb.&lt;/li&gt;
&lt;li&gt;Turned local team knowledge into company-wide knowledge by creating tooling and infrastructure to publish documentation from dozens of code repositories to a single internal site.&lt;/li&gt;
&lt;li&gt;Increased learning pace of a product organization delivering new features once a quarter, to shipping multiple times per week.&lt;/li&gt;
&lt;li&gt;Guided direct reports through COVID-19 remote transitions, two rounds of layoffs, and a business pivot. Forged a gritty team through a difficult downturn.&lt;/li&gt;
&lt;li&gt;Revamped software engineer hiring process to remote positions and a higher bar.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;tile full&#34;&gt;
&lt;h3 id=&#34;r-ga-portland-or&#34;&gt;&lt;a href=&#34;http://rga.com&#34;&gt;R/GA&lt;/a&gt; - Portland OR&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;2015-2016 &amp;ndash; Sr. SWE&lt;/strong&gt;&lt;br /&gt;
Premier design, branding, and advertising agency.&lt;br /&gt;
Was embedded at Nike Headquarters on the &lt;a href=&#34;https://www.nike.com/nike-by-you&#34;&gt;Nike By You (aka Nike iD)&lt;/a&gt; product customization team.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Delivered mobile frontend for one of Nike&amp;rsquo;s most profitable online experiences.&lt;/li&gt;
&lt;li&gt;Unlocked new sales drivers by working hand-in-hand with Nike.com teams to provide API integration between our embedded app and product pages.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;tile&#34;&gt;
&lt;h3 id=&#34;cascade-energy-portland-or&#34;&gt;&lt;a href=&#34;http://www.cascadeenergy.com&#34;&gt;Cascade Energy&lt;/a&gt; - Portland, OR&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;2012-2015 &amp;ndash; Sr. SWE &amp;lt; SWE&lt;/strong&gt;&lt;br /&gt;
Industrial Energy Efficiency Consultancy.&lt;br /&gt;
Full-stack development of industrial energy management tool &lt;a href=&#34;http://energysensei.com/&#34;&gt;SENSEI&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Built scalable utility meter ingest system on AWS EC2, S3, SQS, and DynamoDb.&lt;/li&gt;
&lt;li&gt;Developed calculation UI and API enabling expert mechanical engineers to create models on time-series measurements.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;tile&#34;&gt;
&lt;h3 id=&#34;id-branding-liquid-agency-portland-or&#34;&gt;ID Branding/&lt;a href=&#34;http://www.liquidagency.com&#34;&gt;Liquid Agency&lt;/a&gt; - Portland, OR&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;2010-2012 &amp;ndash; Jr. SWE&lt;/strong&gt;&lt;br /&gt;
Brand advertising, design, strategy and experience agency. ID Branding was acquired by Liquid Agency in early 2011.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;High level design and brand communication web applications for clients.&lt;/li&gt;
&lt;li&gt;Microsites for Nike, Trimet, and other regional clients.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;education&#34;&gt;Education&lt;/h2&gt;
&lt;p&gt;Portland State University, September 2009-Jan 2010 (No Degree)&lt;br /&gt;
Pacific University, August 2004 &amp;ndash; March 2006 (No Degree)&lt;br /&gt;
University of Oregon September 2002 &amp;ndash; June 2004 (No Degree)&lt;br /&gt;
La Grande High School, Graduated 2002&lt;br /&gt;&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
