<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title># Codeholics</title><link href="https://codeholics.com/" rel="alternate"></link><link href="https://codeholics.com/feeds/all.atom.xml" rel="self"></link><id>https://codeholics.com/</id><updated>2022-06-20T18:39:00-04:00</updated><entry><title>Home Network Overhaul with Enterprise Techniques</title><link href="https://codeholics.com/home-network-overhaul-with-enterprise-techniques.html" rel="alternate"></link><published>2022-06-20T18:39:00-04:00</published><updated>2022-06-20T18:39:00-04:00</updated><author><name>vesc</name></author><id>tag:codeholics.com,2022-06-20:/home-network-overhaul-with-enterprise-techniques.html</id><summary type="html">&lt;h3 id="pre-reqs"&gt;Pre-Reqs&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;An understanding of IP networking&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="intro"&gt;Intro&lt;/h3&gt;
&lt;p&gt;Most home users have a flat network on the private range of &lt;code&gt;192.168.1.1/24&lt;/code&gt;. This allows for 254 devices including the router.
This is alright for most users but has become more of a concern with the lacking security in …&lt;/p&gt;</summary><content type="html">&lt;h3 id="pre-reqs"&gt;Pre-Reqs&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;An understanding of IP networking&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="intro"&gt;Intro&lt;/h3&gt;
&lt;p&gt;Most home users have a flat network on the private range of &lt;code&gt;192.168.1.1/24&lt;/code&gt;. This allows for 254 devices including the router.
This is alright for most users but has become more of a concern with the lacking security in IoT devices. 
With this said this post will not be an in depth look into the topic of home IoT devices but more of a look at how I have used
what I have learned through my career in IT to plan the setup of my home network. This setup is not for most people. The concepts
I learned were picked up many years ago in CCNA classes. I have also implemented and worked directly with advanced networking topologies
over my 20+ year career in various positions throughout the industry. This post is in no way a &lt;em&gt;flex&lt;/em&gt;. I did this on a small budget using
what I had available to me and bought adequate hardware for things I didn't have. &lt;/p&gt;
&lt;h3 id="planning"&gt;Planning&lt;/h3&gt;
&lt;p&gt;All good network implementations start with a plan. It is important to understand the goals you are trying to achieve with
your current networking needs and understand what your future needs might be. If you put in the up front work to design your network 
properly, it will grow as your needs grow saving you valuable future time.&lt;/p&gt;
&lt;h4 id="my-goals"&gt;My Goals&lt;/h4&gt;
&lt;p&gt;My environment has the standard things most houses have: laptops, phones, Roku sticks, personal assistance, cameras... 
but I also have a bit more than the average home. I have a file server, beefy 4U server and a Raspberry Pi cluster. 
I wanted to create a few VLANs and rich firewall rules to keep these devices orginized and make sure they do not get out of line. &lt;/p&gt;
&lt;h4 id="network-topology-diagram"&gt;Network Topology Diagram&lt;/h4&gt;
&lt;p&gt;Once you understand your goal, it is time to get a high level understanding of what you have and what you will need to achieve that goal.
In the enterprise space, you would use expensive software like MS Visio to do a network diagram, but this can be done with other software that is 
freely or openly available to everyone. For this project and for projects I have helped out with in the past I use the Google Suite.
For the network diagram I use Google Drawings. For the network address layout and VLAN switch port assignments I use Google Sheets. 
This method has served me well when I want to collaborate with people on a project or just use multiple devices to access the project's
artifacts.  &lt;/p&gt;
&lt;p&gt;When it comes to network diagrams, it is nice to have official asset images. Network topology images can be downloaded from Cisco:
&lt;a href="https://www.cisco.com/c/en/us/about/brand-center/network-topology-icons.html"&gt;Network Topology Icons&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I unzipped the JPG icons and uploaded them into my Google Drive to have them available for my Google Drawings. 
Now, if you have not taken CCNA classes, read networking books or worked in this space these icons might not mean anything to you. 
The icons I will use in my network topology diagram are:  &lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center;"&gt;&lt;/th&gt;
&lt;th style="text-align: center;"&gt;&lt;/th&gt;
&lt;th style="text-align: center;"&gt;&lt;/th&gt;
&lt;th style="text-align: center;"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;strong&gt;Modem&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: center;"&gt;&lt;strong&gt;Firewall Router&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: center;"&gt;&lt;strong&gt;Switch&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: center;"&gt;&lt;strong&gt;WiFi Router&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;img alt="modem icon" src="https://codeholics.com/images/networking_icons/modem.jpg"&gt;&lt;/td&gt;
&lt;td style="text-align: center;"&gt;&lt;img alt="firewall router icon" src="https://codeholics.com/images/networking_icons/router_firewall.jpg"&gt;&lt;/td&gt;
&lt;td style="text-align: center;"&gt;&lt;img alt="switch icon" src="https://codeholics.com/images/networking_icons/workgroup_switch.jpg"&gt;&lt;/td&gt;
&lt;td style="text-align: center;"&gt;&lt;img alt="wifi router icon" src="https://codeholics.com/images/networking_icons/wireless_router.jpg"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;I could have used an Access Point icon instead of the WiFi Router icon since  the router will only be acting as an Access Point, 
but this is for my home network and not an enterprise network, so I know what it is. With that said, you do not need to 
do icons if this is just for you. You can just do boxes or whatever makes sense to you.&lt;/p&gt;
&lt;p&gt;Here is what the first version of my network topology diagram looked like:&lt;/p&gt;
&lt;p&gt;&lt;img alt="network topology v1" src="https://codeholics.com/images/home_network_overhaul/network_topology_v1.webp"&gt;&lt;/p&gt;
&lt;p&gt;The things that were known going into the first iteration of the network topology design:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I was going to re-use my current Asus router in AP mode&lt;/li&gt;
&lt;li&gt;I needed a 24 port switch that supported VLANs&lt;/li&gt;
&lt;li&gt;I needed a more feature rich firewall router that supports VLANs and rich firewall rules&lt;/li&gt;
&lt;li&gt;I was going to use the 192.168.0.0/16 address space&lt;/li&gt;
&lt;li&gt;192.168.1.0/24 was going to be my network management subnet&lt;/li&gt;
&lt;li&gt;192.168.2.0/24 was going to be my wireless device subnet&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="vlan-network-assignment"&gt;VLAN Network Assignment&lt;/h4&gt;
&lt;p&gt;The next task is laying out all the additional VLANs and subnets that are needed.&lt;/p&gt;
&lt;p&gt;&lt;img alt="network vlan layout" src="https://codeholics.com/images/home_network_overhaul/network_vlan_layout.webp"&gt;&lt;/p&gt;
&lt;p&gt;At this point, it's time to start acquiring the hardware needed to get the job done.&lt;/p&gt;
&lt;h3 id="hardware"&gt;Hardware&lt;/h3&gt;
&lt;p&gt;What I had:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://amzn.to/3bnH7VX"&gt;Asus AC1900 (RT-AC68U)&lt;/a&gt;  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Asus RT-AC68U is a basic Wifi router with a 4 port switch. I had this for only a few months as my Asus RT-AC66U power switch gave out after its loyal service for about 5 years. 
The RT-AC68U has never been stable in Router Mode. I had constant connection issues and had to reboot it often. My hope in continuing to use the device was that 
these issues might go away in AP Mode. (Spoiler Alert!!) So far so good in using it in AP Mode.&lt;/p&gt;
&lt;p&gt;Probably most important is the UPS. It is not depicted in the Network Topology Diagram. It would be in a Network Rack Diagram. I am not going to go over the Network Rack Diagram in this post. 
If you are going to drop some money on equipment you need to protect it. I have a CyberPower UPS that I have been using 
for a few years. It is not rack mounted, but I had this long before I had a rack. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://amzn.to/3Ngvo92"&gt;CyberPower CP900AVR&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If I were going to buy a UPS for this project I would probably go with this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://amzn.to/39PEYSM"&gt;CyberPower OR700LCDRM1U Smart App LCD UPS, 700VA/400W, 6 Outlets, AVR, 1U Rackmount&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The price is good and it is a 1U design&lt;/p&gt;
&lt;p&gt;New hardware:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://protectli.com/product/fw2/"&gt;Protechtli FW20216&lt;/a&gt;  &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://protectli.com/vault-2-port/"&gt;Protechtli FW2B&lt;/a&gt;  &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I included two links because the model I have is no longer available and has been updated to a newer model. Before I go on about how nice this device is, it is
probably worth a reminder that I am not getting paid by Protechtli for this post. &lt;/p&gt;
&lt;p&gt;I got my hardware from a friend who decided the device was not right for their environment so I got it for the low, low price of free. I had never heard of the company 
Protechtli but I was immediately impressed. First thing I noticed when I unpacked this device was the quality of the case. It is a beautifully designed, thick, all aluminum case.&lt;/p&gt;
&lt;p&gt;The specs on the device should have plenty of power for running in my environment. These devices do not come pre-loaded with an OS. I am using PFSense CE on my device. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://amzn.to/3ndATL4"&gt;TP-Link TL-SG1024DE&lt;/a&gt;  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When I was searching around for a switch I had in mind a few things I wanted and a dollar amount I wanted to stay under. I also didn't want to buy used network hardware off of ebay because you have no idea the device's history, and Cisco IOS is behind a pay wall. The TP-Link TL-SG1024DE 24 port switch is a really nice, 
feature rich budget switch. It is low power, and it has a fanless design. &lt;/p&gt;
&lt;p&gt;Things this had that I neeeded:&lt;br&gt;
&lt;em&gt; VLAN
* LAG
Things it was lacking that I wanted:&lt;br&gt;
&lt;/em&gt; POE
* Trunking&lt;/p&gt;
&lt;p&gt;In the future when needs and budget grow, I will look into a 24 port switch that offers the things I want. However, you are looking at $200+ extra for a switch with these features. At the moment this was not in the network project budget. You really cannot beat the price tag on this switch for the feature set it provides. I will also need to update my AP or see if maybe another firmware would support multiple VLANs in AP mode. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://amzn.to/3bpUu84"&gt;NavePoint 9U Wall Mount IT Open Frame 19 Inch Rack with Swing Out Hinged Gate Black&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://amzn.to/3OCipzK"&gt;AC Infinity Vented Cantilever 1U Universal Rack Shelf&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I have the 9U rack mounted to a fire rated backer board in a spot down in the basement. I had already had the spot setup as I have been wanting to do this project for sometime. The rack was very easy to mount. I was able to do it all myself without having to call anyone over to lend a hand. 
The 1U shelves worked out really well for keeping items that were not rack mountable in a nice location within the rack.&lt;/p&gt;
&lt;h3 id="finished-network-topology-diagram"&gt;Finished Network Topology Diagram&lt;/h3&gt;
&lt;p&gt;Once the hardware is selected, a little more detail can be added to the final topology diagram.&lt;/p&gt;
&lt;p&gt;&lt;img alt="network topology v2" src="https://codeholics.com/images/home_network_overhaul/network_topology_v2.webp"&gt;&lt;/p&gt;
&lt;h3 id="switch-port-vlan-assignment-diagram"&gt;Switch Port VLAN Assignment Diagram&lt;/h3&gt;
&lt;p&gt;The reason this is not included with the planning is due to the fluid nature of the document, and the port configuration can depend on the features of the switch. 
My configuration is not finalized as of this moment, as I have not setup any LAG groups and the additional ports for the Pi Cluster. This will all be done at a later time.&lt;/p&gt;
&lt;p&gt;Having a document like this is handy for easy deployment and future troubleshooting. &lt;/p&gt;
&lt;p&gt;&lt;img alt="Network Switch Port Assignment" src="https://codeholics.com/images/home_network_overhaul/switch_port_assignment.webp"&gt;&lt;/p&gt;
&lt;h3 id="conclusion"&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;The main goal of this post was to introduce some of the upfront processes and tasks that go into enterprise network planning and some of the techniques that can be utilized to keep a more complex networking project in order. 
The techniques for enterprise deployments can be applied on a home network as well if your needs are a little more demanding like mine. &lt;/p&gt;
&lt;p&gt;There is one document that I should have gone over but will not for this small project: The Rack Level Diagram. This diagram displays all the equipment at the rack level so you know where everything will be placed and can make sure it all fits. I didn't do one of these because I simply had an idea in my head of how all these things would fit together, and since it was just for me I didn't need it. &lt;/p&gt;
&lt;p&gt;The topic of computer networking is very deep. While some of the hardware has gone virtual the concepts and practices remain the same. Having a solid foundation in networking has given me an edge throughout my career working with virtulization, containerization and cloud technologies. 
I would like to give a special thanks to George Markwick who has been an amazing friend and mentor throughout my career, and it was he who taught me these techniques early on in my career while we were designing and building out IDFs, MDFs and Data Centers. &lt;/p&gt;
&lt;p&gt;I am going to leave this post off with a few pictures of everything racked up:  &lt;/p&gt;
&lt;p&gt;&lt;img alt="just mounted rack" src="https://codeholics.com/images/home_network_overhaul/just_mounted.webp"&gt;
&lt;img alt="before switch" src="https://codeholics.com/images/home_network_overhaul/before_switch.webp"&gt;
&lt;img alt="rack as of this post" src="https://codeholics.com/images/home_network_overhaul/rack_today.webp"&gt;&lt;/p&gt;
&lt;p&gt;My next steps are getting a 1U cable tray to get those cables under control and getting a rack mount for the Pi Cluster.
If you enjoyed this post, please consider becoming a sponsor. The funds will be used to help keep Codeholics rolling.  &lt;/p&gt;
&lt;h3 id="links"&gt;Links:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.cisco.com/c/en/us/about/brand-center/network-topology-icons.html"&gt;Network Topology Icons&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amzn.to/3bnH7VX"&gt;Asus AC1900 (RT-AC68U)&lt;/a&gt;  &lt;/li&gt;
&lt;li&gt;&lt;a href="https://amzn.to/3Ngvo92"&gt;CyberPower CP900AVR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amzn.to/39PEYSM"&gt;CyberPower OR700LCDRM1U Smart App LCD UPS, 700VA/400W, 6 Outlets, AVR, 1U Rackmount&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://protectli.com/product/fw2/"&gt;Protechtli FW20216&lt;/a&gt;  &lt;/li&gt;
&lt;li&gt;&lt;a href="https://protectli.com/vault-2-port/"&gt;Protechtli FW2B&lt;/a&gt;  &lt;/li&gt;
&lt;li&gt;&lt;a href="https://amzn.to/3ndATL4"&gt;TP-Link TL-SG1024DE&lt;/a&gt;  &lt;/li&gt;
&lt;li&gt;&lt;a href="https://amzn.to/3bpUu84"&gt;NavePoint 9U Wall Mount IT Open Frame 19 Inch Rack with Swing Out Hinged Gate Black&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amzn.to/3OCipzK"&gt;AC Infinity Vented Cantilever 1U Universal Rack Shelf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/sponsors/jessecooper"&gt;Github Sponsors&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Hardware"></category><category term="networking"></category><category term="hardware"></category><category term="review"></category><category term="firewall"></category><category term="pfsense"></category><category term="tplink"></category><category term="asus"></category><category term="router"></category><category term="switch"></category><category term="vlan"></category><category term="infosec"></category></entry><entry><title>Mycroft Personal Assistant Setup Part 2</title><link href="https://codeholics.com/mycroft-personal-assistant-setup-part-2.html" rel="alternate"></link><published>2022-06-16T18:39:00-04:00</published><updated>2022-06-16T18:39:00-04:00</updated><author><name>vesc</name></author><id>tag:codeholics.com,2022-06-16:/mycroft-personal-assistant-setup-part-2.html</id><summary type="html">&lt;h3 id="intro"&gt;Intro&lt;/h3&gt;
&lt;p&gt;If you have followed the &lt;a href="https://codeholics.com/mycroft-personal-assistant-setup-part-1.html"&gt;part 1&lt;/a&gt; of this Mycroft personal assistant setup
you have a standard Mycroft personal assistant with either the &lt;code&gt;Hey Mycroft&lt;/code&gt; wake word or you tried to set it up with a custom wake word. 
If that customer wake word is using Pocketsphinx it is …&lt;/p&gt;</summary><content type="html">&lt;h3 id="intro"&gt;Intro&lt;/h3&gt;
&lt;p&gt;If you have followed the &lt;a href="https://codeholics.com/mycroft-personal-assistant-setup-part-1.html"&gt;part 1&lt;/a&gt; of this Mycroft personal assistant setup
you have a standard Mycroft personal assistant with either the &lt;code&gt;Hey Mycroft&lt;/code&gt; wake word or you tried to set it up with a custom wake word. 
If that customer wake word is using Pocketsphinx it is probably getting an unlivable amount of false positives. 
In part 2 of this series I am going to walk you through setting up a custom wake word for Mycroft using &lt;a href="https://github.com/MycroftAI/mycroft-precise"&gt;mycroft-precise&lt;/a&gt;. 
As of the time of writing this the setup was not all that straight forward and the processes of training a custom wake word is a bit more involved than one might think. 
Also &lt;a href="https://github.com/MycroftAI/mycroft-core"&gt;mycroft-core&lt;/a&gt; defaults to an older version of Precise and the Precise Runner. A wake word you train with the newer version of Precise
will not run on an older version. I also ran into an &lt;a href="https://github.com/MycroftAI/mycroft-precise/issues/158"&gt;issue&lt;/a&gt; along the way and the requirements for the Precise project were a bit out of date. 
This lead me to opening up a &lt;a href="https://github.com/MycroftAI/mycroft-precise/pull/216"&gt;PR&lt;/a&gt; and I am currently running on my fork until the PR is merged. It is nice to be able to contribute back to a great project.
First I will walk through the project setup and training of the custom wake word. Then I will get into the precise configuration for the PA. &lt;/p&gt;
&lt;h3 id="custom-wake-word-project-setup"&gt;Custom Wake Word Project Setup&lt;/h3&gt;
&lt;p&gt;For recording I used two different microphones that I had within my environment to train the wake word. First I used my Blue Snowball
but when I ran my model on my Picroft with the ReSpeaker hat I was not getting good results so I started training directly on the Mycroft device itself. 
Doing this gave me much better results.&lt;/p&gt;
&lt;p&gt;Start off by creating the following project structure. If time permits maybe I will make a cookie cutter for this in the future. &lt;/p&gt;
&lt;h4 id="the-project-structure"&gt;The project structure&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jarvis
├── models
├── not-wake-word
├── README.md
├── test
│   ├── not-wake-word
│   └── wake-word
└── wake-word
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I wanted my custom wake word to be &lt;code&gt;Jarvis&lt;/code&gt; not &lt;code&gt;Hey Jarvis&lt;/code&gt; just &lt;code&gt;Jarvis&lt;/code&gt;. Now, I was already setting myself up for trouble because most guides tell you to use a two word wake word 
but if Tony Stark can just say, "Jarvis, bring up the plans for the Mark 5." I should be able to as well. With that said I have been able to get good results from my single word wake word 
so I wont advise against trying it for yourself.  &lt;/p&gt;
&lt;h3 id="wake-word-collection"&gt;Wake word collection&lt;/h3&gt;
&lt;p&gt;Now start recording the wake word with Precise using the following command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;precise-collect
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will collect &lt;code&gt;.wave&lt;/code&gt; files in the current directory. This cli tool has a few options but I think one major thing it is lacking is the ability to set the path of where you want to collect. 
If you would like to set the output file name use:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;precise-collect jarvis-###
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will create &lt;code&gt;jarvis-000.wave&lt;/code&gt; and so on as you keep recording. Think of this project as any other software project that you will need to work on over time.
With that in mind you want to make unique names for each recording session. Here is a peek at my wake-word folder:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;...
-rw-r--r-- 1 pi pi  64078 Sep 24  2021 jarvis-eebfbb38-db51-4a83-98dd-8a0712b32a7e.wav
-rw-r--r-- 1 pi pi  69676 Sep 24  2021 jarvis-ef72a2b2-0ea2-495c-af10-eaf12255ec9d.wav
-rw-r--r-- 1 pi pi  81964 Sep 24  2021 jarvis-fa85b5d8-5803-43f9-a6aa-9dd67034be14.wav
-rw-r--r-- 1 pi pi  81964 Sep 24  2021 jarvis-fb675e0a-1ac8-4a45-b9d8-36d454c598bc.wav
-rw-r--r-- 1 pi pi  67628 Oct 22  2021 jarvis-with-radiohead-00.wav
-rw-r--r-- 1 pi pi  75820 Oct 22  2021 jarvis-with-radiohead-01.wav
-rw-r--r-- 1 pi pi  67628 Oct 22  2021 jarvis-with-radiohead-02.wav
-rw-r--r-- 1 pi pi  67628 Oct 22  2021 jarvis-with-radiohead-03.wav
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;At one point I used a little bash-fu to give some old recordings UUIDs to make sure not to clobber them when I just had the files numbered. 
At one point I was listening to Radiohead and I was getting a lot of false positives so I did a recording session with Radiohead playing in the background. 
It is important to do a good amount of wake word recordings from different distances from the mic as you might be half way across the room and want to say a command. &lt;/p&gt;
&lt;p&gt;One important thing to do before starting collection is stop your Mycroft services: &lt;code&gt;mycroft-stop all&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;It is just as important to have a well populated &lt;code&gt;not-wake-word&lt;/code&gt; folder. Record yourself saying words that might sounds like your wake word but are not. 
Also, the &lt;a href="https://github.com/MycroftAI/Precise-Community-Data/tree/master/not-wake-words"&gt;Precise-Community-Data&lt;/a&gt; has a good set of &lt;code&gt;not-work-words&lt;/code&gt; recordings to include in your project.&lt;/p&gt;
&lt;p&gt;Once you have your &lt;code&gt;wake-word&lt;/code&gt; and &lt;code&gt;not-wake-word&lt;/code&gt; folder populated grab a subset to include in your &lt;code&gt;test&lt;/code&gt; sub folders. Now take the first pass at training the wake word model.
Navigate to your models folder and use the following command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;precise-train -e 600 jarvis.net ../
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Where &lt;code&gt;-e&lt;/code&gt; is for number of EPOCHS to train the mode, jarvis.net is the NN model and &lt;code&gt;../&lt;/code&gt; is the path to the project data to train the model.
Once this is completed convert the jarvis.net file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;precise-convert jarvis.net
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After all this the models folder will look something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ls ./jarvis/models/
jarvis.epoch  jarvis.logs  jarvis.net  jarvis.net.params  jarvis.pb  jarvis.pb.params  jarvis.pbtxt  jarvis.trained.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now that you have a wake word model it is time to test it out and see if it works. This can be done using the &lt;code&gt;precise-listen&lt;/code&gt; command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;precise-listen jarvis.net
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This command will give you a bit of visual feedback on how well your wake word is doing. 
This tool can also be used to find false positives within your environment.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;precise-listen jarvis.net -d ../not-wake-word
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will put all the trigger words into the &lt;code&gt;not-wake-word&lt;/code&gt; folder. I have ran this over a few days while I am in meetings and what not to help    catch false positives.
Doing this has really helped improve the accuracy of my wake word. &lt;/p&gt;
&lt;h3 id="setting-up-picroft-to-use-the-latest-precise-engine"&gt;Setting up Picroft to use the latest precise-engine&lt;/h3&gt;
&lt;p&gt;Since I trained my model with a newer version of precise I needed to update the precise running binary on my Mycroft PA. 
The Precise Engine binary can be found in &lt;code&gt;/home/pi/.mycroft/precise&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="o"&gt;/.&lt;/span&gt;&lt;span class="n"&gt;mycroft&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;precise&lt;/span&gt;
&lt;span class="n"&gt;wget&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;MycroftAI&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mycroft&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;precise&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;releases&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;download&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;precise&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;engine_0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="n"&gt;_armv7l&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gz&lt;/span&gt;
&lt;span class="n"&gt;tar&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;xvf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;precise&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;engine_0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="n"&gt;_armv7l&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gz&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now you should have the latest version of the precise-engine installed. &lt;/p&gt;
&lt;h3 id="installing-mycroft-precise-fork"&gt;Installing mycroft-precise fork&lt;/h3&gt;
&lt;p&gt;Anytime you have to start using a fork of a project you are setting yourself up for a bit of work.
At this time I am setup with the dev upstream release of mycroft-core and I am installing my fork of mycroft-precise into the venv.
The issue with this is when Picroft restarts it will pull down the latest dev and this can clobber the locally installed precise.
I think in the end I will fork mycroft-core as well and run on both forks and manage my own upgrade process of the forks from upstream. 
This is not an ideal setup for people looking for a set it and forget it type PA but I am going to be creating custom skills 
and contributing where I can so this works for me. &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;clone&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;fork&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;change&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;you&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;will&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;be&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;working&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;your&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;own&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;fork&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;clone&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;https&lt;/span&gt;:&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="nv"&gt;github&lt;/span&gt;.&lt;span class="nv"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;jessecooper&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;mycroft&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;precise&lt;/span&gt;.&lt;span class="nv"&gt;git&lt;/span&gt;
&lt;span class="nv"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;mycroft&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;precise&lt;/span&gt;
#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;mycroft&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;venv&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;run&lt;/span&gt;
&lt;span class="nv"&gt;pip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;requirements&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;requirements&lt;/span&gt;.&lt;span class="nv"&gt;txt&lt;/span&gt;
&lt;span class="nv"&gt;pip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="mycroft-wake-word-config"&gt;Mycroft wake word config&lt;/h3&gt;
&lt;p&gt;With all of this done it is time to configure Mycroft to use the custom listener.
Edit &lt;code&gt;~/.config/mycroft/mycroft.conf&lt;/code&gt; to use the custom listener:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;  &amp;quot;listener&amp;quot;: {
    &amp;quot;wake_word&amp;quot;: &amp;quot;jarvis&amp;quot;,
    &amp;quot;phoneme_duration&amp;quot;: 240
  },
  &amp;quot;hotwords&amp;quot;: {
    &amp;quot;jarvis&amp;quot;: {
      &amp;quot;module&amp;quot;: &amp;quot;precise&amp;quot;,
      &amp;quot;phonemes&amp;quot;: &amp;quot;JH AA R V AH S .&amp;quot;,
      &amp;quot;threshold&amp;quot;: 1e-20,
      &amp;quot;lang&amp;quot;: &amp;quot;en-us&amp;quot;,
      &amp;quot;local_model_file&amp;quot;: &amp;quot;/home/pi/jarvis/models/jarvis.pb&amp;quot;,
      &amp;quot;sensitivity&amp;quot;: 0.5,
      &amp;quot;trigger_level&amp;quot;: 3
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Of course replace &lt;code&gt;jarvis&lt;/code&gt; with the name of your custom wake word.&lt;/p&gt;
&lt;p&gt;The final thing to do is restart your Mycroft services. &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mycroft-stop all
mycroft-start all
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="conclusion"&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;This is how I have set up Picroft with a custom wake word. I am sure one could get more stability if they went with the master version of mycroft-core 
and trained the wake word on mycroft-precise 0.2. I personally do not mind working off of my own forks because I like contributing back to projects like this where I can 
but this is not a path for everyone. One very  awesome thing about having a custom wake word that you have only trained with your voice is that I find it only response to my voice. 
This is different from most commercial PAs where you can walk into someones house and potentially just start messing with a persons PA. 
It may take a few training sessions to get it dialed in but it is fairly rare now that I get a false positive. &lt;/p&gt;
&lt;p&gt;Part 3 of this build will take some time to come out as I am a person with way to many projects. One of those being a Codeholics theme redesign. For that post I will either
go into getting the Mycroft GUI up or creating a custom skill. If you have enjoyed either of the posts on my Mycroft setup please think about becoming a
&lt;a href="https://github.com/sponsors/jessecooper"&gt;sponsor&lt;/a&gt;. &lt;/p&gt;
&lt;h3 id="links"&gt;Links&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/MycroftAI/mycroft-precise"&gt;mycroft-precise&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jessecooper/mycroft-precise"&gt;mycroft-precise fork&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/MycroftAI/mycroft-precise/wiki/Training-your-own-wake-word"&gt;mycroft-precise wiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/MycroftAI/mycroft-precise/wiki/Training-your-own-wake-word"&gt;Precise-Community-Data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/sponsors/jessecooper"&gt;Github Sponsors&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Software"></category><category term="ai"></category><category term="coding"></category><category term="mycroft"></category><category term="raspberrypi"></category><category term="pi4"></category><category term="python"></category><category term="respeaker"></category><category term="hardware"></category><category term="opensource"></category></entry><entry><title>Mycroft Personal Assistant Setup Part 1</title><link href="https://codeholics.com/mycroft-personal-assistant-setup-part-1.html" rel="alternate"></link><published>2021-10-05T07:39:00-04:00</published><updated>2021-10-05T07:39:00-04:00</updated><author><name>vesc</name></author><id>tag:codeholics.com,2021-10-05:/mycroft-personal-assistant-setup-part-1.html</id><summary type="html">&lt;h3 id="intro"&gt;Intro&lt;/h3&gt;
&lt;p&gt;I have been fascinated by voice computing/electronic personal assistance for many years now but I am not a fan of inviting big tech into my home with a black box speaker. Because of this I have always looked for a open source solution.
Early on, I was doing …&lt;/p&gt;</summary><content type="html">&lt;h3 id="intro"&gt;Intro&lt;/h3&gt;
&lt;p&gt;I have been fascinated by voice computing/electronic personal assistance for many years now but I am not a fan of inviting big tech into my home with a black box speaker. Because of this I have always looked for a open source solution.
Early on, I was doing a bit of work with Jasper but I quickly ran out of time to play with that project. Over the years as electronic personal assistance become more popular I continued looking for a open alternative.
In a conversation with a friend, I was pointed to the Mycroft project. I purchased a Raspberry Pi 4 for another reason and ended up not need it so it was looking for something to do with it. In another 
conversation a friend pointed me to the ReSpeaker 2-mic Pi Hat. So, all the pieces were falling into place all I needed was a little speaker that I was able to find fairly easy. &lt;/p&gt;
&lt;h3 id="hardware-list"&gt;Hardware List&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;part&lt;/th&gt;
&lt;th&gt;cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Raspberry Pi 4 Cancan Kit&lt;/td&gt;
&lt;td&gt;$106.24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ReSpeaker 2-mic Pi Hat&lt;/td&gt;
&lt;td&gt;$12.74&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MakerHawk 4 Ohm 3 Watt Speaker&lt;/td&gt;
&lt;td&gt;$9.75&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JST XH 2.54mm 24 AWG&lt;/td&gt;
&lt;td&gt;$2.56&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7" LCD Touch Screen&lt;/td&gt;
&lt;td&gt;$53.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7" Display Case&lt;/td&gt;
&lt;td&gt;$12.99&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Total: $194.72&lt;/p&gt;
&lt;h3 id="the-build"&gt;The Build&lt;/h3&gt;
&lt;p&gt;The Raspberry Pi 4 Cancan kit comes with every you really need to get going with the Pi4 and the power cable has a on/off switch that is actually a really nice feature to have. The case the kit comes with works alright with the
ReSpeaker 2-mic Pi Hat. The only drawback is you will not be able to close the top when the hat is on but that is alright because you need to attach the speaker to the JST speaker port. The MakerHawk speaker comes with a JST-PH 2.0mm
connection. The ReSpeaker hat has a JST XH 2.54mm plug. I cut the JST head off the speaker and crimped on a 2-pin Dupont connection to the speaker and the JST XH lead. The ReSpeaker hat has a power connection on it. This was
a bit confusing to me because I was not sure if I had to plug the power into the hat and none of the docs were very clear on this. I started out with it plug into the hat but while doing the software setup I got some odd behavior and ended up
moving to the normal power port on the Pi4. I think this could be caused by the different power requirements between the older Pi models and the Pi4 but either way it is not needed to operate the hat. &lt;/p&gt;
&lt;p&gt;&lt;img alt="pi4 setup" src="https://codeholics.com/images/picroft.webp"&gt;&lt;br&gt;
&lt;img alt="pi4 setup with screen" src="https://codeholics.com/images/pi-w-screen.webp"&gt;
*ignore Snowball and Topping MX3&lt;/p&gt;
&lt;h3 id="software-setup"&gt;Software Setup&lt;/h3&gt;
&lt;p&gt;Mycroft has a image that is ready made for the Pi called Picroft. I downloaded the image and used &lt;code&gt;dd&lt;/code&gt; to set up the sd card for the Pi. If you need any help doing this we have a small post about 
&lt;a href="https://codeholics.com/make-a-bootable-flash-drive-from-an-iso-file-in-linux.html"&gt;creating bootable flash drives&lt;/a&gt; that covers the process. Once the sd card is ready and loaded into the Pi this is where the fun starts. 
Picroft has a setup wizard that tries to walk you through the setup of your device but with this build being fairly custom the simple path was not the road I could travel. This led me down a long road of trial and error.
First thing was getting the ReSpeaker hat setup and detected. The process for installing the driver is as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# first make sure your image is updated
sudo apt update
# Second grab the driver from github and install it
git clone https://github.com/respeaker/seeed-voicecard.git
cd seeed-voicecard
sudo ./install_arm64.sh
sudo reboot now
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There is an &lt;code&gt;install.sh&lt;/code&gt; file in the repo if you desire the 32 bit driver but we are working with the Pi4 so do not run that install it wont work.  &lt;/p&gt;
&lt;p&gt;After it is installed and you have rebooted you have verify the card is being detected with &lt;code&gt;aplay -l&lt;/code&gt; and &lt;code&gt;arecord -l&lt;/code&gt;.
The output should look something like this:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(.&lt;/span&gt;&lt;span class="n"&gt;venv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="n"&gt;picroft&lt;/span&gt;&lt;span class="o"&gt;:~&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;aplay&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;
&lt;span class="o"&gt;****&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PLAYBACK&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Hardware&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Devices&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;****&lt;/span&gt;
&lt;span class="n"&gt;card&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;bcm2835&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HDMI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bcm2835&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HDMI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;bcm2835&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HDMI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;Subdevices&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Subdevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subdevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Subdevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subdevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Subdevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subdevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Subdevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subdevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="n"&gt;card&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Headphones&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;bcm2835&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Headphones&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bcm2835&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Headphones&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;bcm2835&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Headphones&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;Subdevices&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Subdevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subdevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Subdevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subdevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Subdevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subdevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Subdevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subdevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="n"&gt;card&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;seeed2micvoicec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;seeed&lt;/span&gt;&lt;span class="mi"&gt;-2&lt;/span&gt;&lt;span class="n"&gt;mic&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;voicecard&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bcm2835&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i2s&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;wm8960&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;hifi&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;wm8960&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;hifi&lt;/span&gt;&lt;span class="mi"&gt;-0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;bcm2835&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i2s&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;wm8960&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;hifi&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;wm8960&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;hifi&lt;/span&gt;&lt;span class="mi"&gt;-0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;Subdevices&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Subdevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subdevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;(.&lt;/span&gt;&lt;span class="n"&gt;venv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="n"&gt;picroft&lt;/span&gt;&lt;span class="o"&gt;:~&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arecord&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;
&lt;span class="o"&gt;****&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CAPTURE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Hardware&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Devices&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;****&lt;/span&gt;
&lt;span class="n"&gt;card&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;seeed2micvoicec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;seeed&lt;/span&gt;&lt;span class="mi"&gt;-2&lt;/span&gt;&lt;span class="n"&gt;mic&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;voicecard&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bcm2835&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i2s&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;wm8960&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;hifi&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;wm8960&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;hifi&lt;/span&gt;&lt;span class="mi"&gt;-0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;bcm2835&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i2s&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;wm8960&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;hifi&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;wm8960&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;hifi&lt;/span&gt;&lt;span class="mi"&gt;-0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;Subdevices&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Subdevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subdevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now you will need to set your defaults in pulse audio. The &lt;a href="https://mycroft-ai.gitbook.io/docs/using-mycroft-ai/troubleshooting/audio-troubleshooting#pulseaudio-settings"&gt;Pulseadio Settings&lt;/a&gt; section of the Mycroft audio troubleshooting guide covers this well.
There is another setting I had to make to the Pulse audio daemon configuration file to remove a delay in recording after the wake word was triggered. I will place this here while we are addressing pulse audio settings:&lt;br&gt;
Edit &lt;code&gt;/etc/pulse/daemon.conf&lt;/code&gt; with the following settings:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;resample-method = ffmpeg
default-sample-format = s24le
default-sample-rate = 48000
alternate-sample-rate = 44100
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After this restart pulseaudio:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pulseaudio -k #stop the pulse daemon
pulseaudio -D #start the pulse daemon
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The last item for the base setup is setting the audio settings in the &lt;code&gt;mycroft.conf&lt;/code&gt; file`.&lt;br&gt;
Mycorft will look for configurations in 3 locations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;remote - pulled from the home.mycroft.ai&lt;/li&gt;
&lt;li&gt;system - &lt;code&gt;/etc/mycroft/mycroft.conf&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;user - &lt;code&gt;~/.config/mycroft/mycroft.conf&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I copied the system config to the user location:
&lt;code&gt;cp /etc/mycroft/mycroft.conf ~/.config/mycroft/mycroft.conf&lt;/code&gt;
and made the following change to the change:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;   &amp;quot;play_wav_cmdline&amp;quot;: &amp;quot;aplay %1&amp;quot;,
   &amp;quot;play_mp3_cmdline&amp;quot;: &amp;quot;mpg123 %1&amp;quot;,
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Essentially removing the hardware setting and using the system defaults we set earlier. &lt;/p&gt;
&lt;p&gt;Once all this is done you can run a few tests:&lt;br&gt;
&lt;code&gt;mycroft-mic-test&lt;/code&gt;&lt;br&gt;
If the results are good you can fire up mycroft:&lt;br&gt;
&lt;code&gt;mycroft-start all&lt;/code&gt;&lt;br&gt;
Then run the mycroft cli tool:&lt;br&gt;
&lt;code&gt;mycroft-cli-client&lt;/code&gt;&lt;br&gt;
From here it will run you through the setup of your mycroft device and registering it with home.mycroft.ai.&lt;/p&gt;
&lt;h3 id="conclusion"&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;At this point you have a mycroft device. If you are like me and do not want the standard &lt;code&gt;hey mycroft&lt;/code&gt; wakeword that uses precise you are getting a bunch of false positives on your wakeword because pocketsphinx is just not accurate enough.
In my next post in this &lt;em&gt;mycroft series&lt;/em&gt; I will run you through training a custom wake word with Precise to fix this issue. I hope to take this series all the way to the point where the microft devices can be 100% offline. &lt;/p&gt;
&lt;h3 id="links"&gt;Links:&lt;/h3&gt;
&lt;h4 id="hardware"&gt;Hardware&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://amzn.to/3D7XZvB"&gt;Raspberry Pi 4 Cancan Kit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amzn.to/3Tj8Bxq"&gt;Respeaker 2-mic Pi Hat&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amzn.to/3D7uPwv"&gt;MakerHawk 4 Ohm 3 Watt Speaker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ebay.com/itm/264394274295"&gt;JST XH2.54mm 24 AWG&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ebay.com/itm/254528464056"&gt;7" LCD Touch Screen&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ebay.com/itm/265113382253"&gt;7" Display Case&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="software"&gt;Software&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mycroft-ai.gitbook.io/docs/using-mycroft-ai/get-mycroft/picroft"&gt;picroft&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://wiki.seeedstudio.com/ReSpeaker_2_Mics_Pi_HAT_Raspberry/"&gt;Respeaker 2 Mics Pi Hat&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/respeaker/seeed-voicecard.git"&gt;Respeaker Driver&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="guides"&gt;Guides&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mycroft-ai.gitbook.io/docs/using-mycroft-ai/troubleshooting/audio-troubleshooting"&gt;mycroft audio troubleshooting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://community.mycroft.ai/t/picroft-rpi4-respeaker-mic-array-v2-0-audio-issues/7585/4"&gt;mycroft delay in recording&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="general"&gt;General&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mycroft.ai/"&gt;mycroft&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Hardware"></category><category term="coding"></category><category term="mycroft"></category><category term="raspberrypi"></category><category term="pi4"></category><category term="python"></category><category term="respeaker"></category><category term="hardware"></category><category term="opensource"></category></entry><entry><title>Using lua-openssl to view x509 attributes</title><link href="https://codeholics.com/using-lua-openssl-to-view-x509-attributes.html" rel="alternate"></link><published>2021-03-25T07:39:00-04:00</published><updated>2021-03-25T07:39:00-04:00</updated><author><name>vesc</name></author><id>tag:codeholics.com,2021-03-25:/using-lua-openssl-to-view-x509-attributes.html</id><summary type="html">&lt;h3 id="intro"&gt;Intro&lt;/h3&gt;
&lt;p&gt;I recently found myself needing to view x509 certificate extended attributes with Lua. 
I had to search far and wide in posts and documentation for the lua-openssl project so, I decided to 
try and put it all in one place.&lt;/p&gt;
&lt;h3 id="install-lua-openssl"&gt;Install lua-openssl&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;luarocks install openssl
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="using-the-openssl-package"&gt;Using the openssl package …&lt;/h3&gt;</summary><content type="html">&lt;h3 id="intro"&gt;Intro&lt;/h3&gt;
&lt;p&gt;I recently found myself needing to view x509 certificate extended attributes with Lua. 
I had to search far and wide in posts and documentation for the lua-openssl project so, I decided to 
try and put it all in one place.&lt;/p&gt;
&lt;h3 id="install-lua-openssl"&gt;Install lua-openssl&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;luarocks install openssl
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="using-the-openssl-package"&gt;Using the openssl package&lt;/h3&gt;
&lt;p&gt;For my needs I needed to use the openssl package in the context of Nginx and using the lua-nginx-module but this can be done in any lua application.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pairs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;openssl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ssl_client_raw_cert&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="n"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pairs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;string&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WARN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Key: &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;type: &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WARN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Key not string: &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tostring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getmetatable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;type: &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WARN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Key not string: &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tostring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot; type: &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tostring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pairs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;string&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WARN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SAN Data: &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot; type: &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;userdata&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tostring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;string&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WARN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SAN Value: &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;toprint&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WARN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SAN Data key not string: &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tostring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot; type: &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;table&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pairs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WARN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Key: &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Type: &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WARN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Key: &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;nil&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WARN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Value: &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="links"&gt;Links:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://zhaozg.github.io/lua-openssl/index.html"&gt;lua-openssl documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zhaozg.github.io/lua-openssl/modules/asn1.html"&gt;lua-openssl asn1 documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/zhaozg/lua-openssl"&gt;lua-openssl asn1 github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Coding"></category><category term="coding"></category><category term="git"></category><category term="crypto"></category><category term="infosec"></category><category term="lua"></category><category term="x509"></category><category term="openssl"></category></entry><entry><title>Git GPG Signing Setup on OSX</title><link href="https://codeholics.com/git-gpg-signing-setup-on-osx.html" rel="alternate"></link><published>2021-02-22T07:39:00-05:00</published><updated>2021-02-22T07:39:00-05:00</updated><author><name>vesc</name></author><id>tag:codeholics.com,2021-02-22:/git-gpg-signing-setup-on-osx.html</id><summary type="html">&lt;h3 id="intro"&gt;Intro&lt;/h3&gt;
&lt;p&gt;Setting up Git commit and tag signing with GnuPG on Mac OSX is not as straight forward as one would like it to be. Here are the steps I used to get it set up. Before hand I was getting the following error:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git commit -S -m &amp;quot;test signing …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;h3 id="intro"&gt;Intro&lt;/h3&gt;
&lt;p&gt;Setting up Git commit and tag signing with GnuPG on Mac OSX is not as straight forward as one would like it to be. Here are the steps I used to get it set up. Before hand I was getting the following error:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git commit -S -m &amp;quot;test signing&amp;quot;
error: gpg failed to sign the data
fatal: failed to write commit object
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="steps"&gt;Steps&lt;/h3&gt;
&lt;p&gt;Getting GnuPG setup and configured properly&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;brew upgrade gnupg
brew link --overwrite gnupg
brew install pinentry-mac
echo &amp;quot;pinentry-program /usr/local/bin/pinentry-mac&amp;quot; &amp;gt;&amp;gt; ~/.gnupg/gpg-agent.conf
killall gpg-agent
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once that is set up configure git&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;you&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;already&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;have&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;done&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;so&lt;/span&gt;
&lt;span class="nv"&gt;gpg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nv"&gt;gen&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;key&lt;/span&gt;
#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;configure&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;git&lt;/span&gt;
&lt;span class="nv"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nv"&gt;global&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;gpg&lt;/span&gt;.&lt;span class="nv"&gt;program&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;gpg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="nv"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nv"&gt;global&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;.&lt;span class="nv"&gt;signingkey&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;key_id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nv"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nv"&gt;global&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;commit&lt;/span&gt;.&lt;span class="nv"&gt;gpgsign&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;true&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;you&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;want&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;sign&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;every&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;commit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Add signing flag when committing or tagging&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git commit -S -m &amp;#39;Signed commit&amp;#39;
git tag -s v1.5 -m &amp;#39;my signed 1.5 tag&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Viewing signatures&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;show&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;v1&lt;/span&gt;.&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="nv"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;log&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="k"&gt;show&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;signature&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Verifying signatures&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# check tag signature
git tag -v &amp;lt;tag-name&amp;gt;
# verify signature before merging
git merge --verify-signatures signed-branch
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I hope this is helpful for people looking to start signing their Git commits on OSX.&lt;/p&gt;
&lt;h3 id="links"&gt;Links:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work"&gt;Git Tools Signing Your Work&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Infosec"></category><category term="coding"></category><category term="git"></category><category term="crypto"></category><category term="infosec"></category><category term="osx"></category><category term="gpg"></category><category term="gnupg"></category></entry><entry><title>Kali Linux (rolling) Blank Screen Fix</title><link href="https://codeholics.com/kali-rolling-blank-screen-fix.html" rel="alternate"></link><published>2020-10-23T13:41:00-04:00</published><updated>2020-10-23T13:41:00-04:00</updated><author><name>vesc</name></author><id>tag:codeholics.com,2020-10-23:/kali-rolling-blank-screen-fix.html</id><summary type="html">&lt;p&gt;Recently I installed the latest Kali Linux on my old Asus Eee PC Netbook and was met with a blinking cursor &lt;code&gt;_&lt;/code&gt; after install. After hitting Alt+F1 and dropping into a terminal I ran all the updates I could and did a reboot with no change to the
DE …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Recently I installed the latest Kali Linux on my old Asus Eee PC Netbook and was met with a blinking cursor &lt;code&gt;_&lt;/code&gt; after install. After hitting Alt+F1 and dropping into a terminal I ran all the updates I could and did a reboot with no change to the
DE issue. I did a quick &lt;code&gt;apt search intel&lt;/code&gt; to see what Intel packages were installable since this has Intel integrated graphics. In the list I found the &lt;code&gt;xserver-xorg-video-intel&lt;/code&gt; package. Once this was installed &lt;code&gt;sudo apt install xserver-xorg-video-intel&lt;/code&gt; and&lt;br&gt;
the system was rebooted the DE was able to load with no issues. I seen a lot of posts on the Kali forum about this issue and instead of creating yet another forum account I decided to post the solution here and maybe this will help someone out who finds themself in the same situation. 
Next on this old Netbook is to try out i3 window manager and see if I can make this old netbook still usable in the modern world. &lt;/p&gt;</content><category term="Linux"></category><category term="linux"></category><category term="kali"></category><category term="blank screen"></category><category term="quick fix"></category></entry><entry><title>Moving a website from Wordpress to Pelican</title><link href="https://codeholics.com/moving_a_website_from_wordpress_to_pelican.html" rel="alternate"></link><published>2019-03-01T20:43:00-05:00</published><updated>2019-03-01T20:43:00-05:00</updated><author><name>vesc</name></author><id>tag:codeholics.com,2019-03-01:/moving_a_website_from_wordpress_to_pelican.html</id><summary type="html">&lt;p&gt;Codeholics has been using Wordpress for its site since its launch back somewhere around 2013. It was great for its time but over the years we have had a number of issues. Plainly put the entire site management and work flow needed to be simplified.  &lt;/p&gt;
&lt;p&gt;Intro: Pelican&lt;/p&gt;
&lt;p&gt;Pelican is a …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Codeholics has been using Wordpress for its site since its launch back somewhere around 2013. It was great for its time but over the years we have had a number of issues. Plainly put the entire site management and work flow needed to be simplified.  &lt;/p&gt;
&lt;p&gt;Intro: Pelican&lt;/p&gt;
&lt;p&gt;Pelican is a static site generator written in Python.  &lt;/p&gt;
&lt;p&gt;First thoughts when people think static site is bringing it back to dialup days but that is not the case with HTML5 and CORS one really dose not need a overly complicated backend to share content with the world.  &lt;/p&gt;
&lt;p&gt;Pelican has a very active community with lots of plugins and themes to choose from. The theme system is very simple as it uses Jinja2 templates and the plugins are just small Python functions that register with the Pelican API. Content for Pelican can be written in REstructured text or Markdown.&lt;/p&gt;
&lt;p&gt;Since our last issue with backups I had already started writing things in Markdown and using Pandocs to convert that into HTML. Then I would take that and put it into the an article in wpadmin. A clunky workflow for sure but I knew my content was safely tucked away in a personal git server. The most clunky thing about it was formatting after the conversion. Simply, none of this made for a good experience to publish content.&lt;/p&gt;
&lt;p&gt;Pelican dose a really nice job of converting Markdown with syntax highlighting and table formatting.  &lt;/p&gt;
&lt;p&gt;Lets now get into using Pelican and porting over WordPress content.&lt;/p&gt;
&lt;p&gt;Since this is Python it's always a good idea to setup a virtual environment:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mkdir codeholics
cd codeholics
python3 -m venv env
source env/bin/activate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now that the site project directory is set up let's install Pelican and initialize the Pelican site.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip install pelican markdown beautifulsoup4 lxml
pelican-quickstart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Next let's pull in the content from WordPress first you will need to extract the xml backup from your WordPress site by going to &lt;em&gt;my site-&amp;gt;settings-&amp;gt;export&lt;/em&gt;. Once this is done run the pelican-import command.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;pelican&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;wpfile&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xml&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;wp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;attach&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;markdown&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;--wp-attach&lt;/code&gt; will attempt to go out and get all the article images&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--markdown&lt;/code&gt; export files in markdown format&lt;/p&gt;
&lt;p&gt;Now that the content is imported in to the content folder we can transpile the site.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pelican content/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This command will generate the static site in the output directory. This can now be published or we can run a local Dev server.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pelican listen
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will create a Dev server on &lt;code&gt;localhost:8000&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;There could be some issues with posts having WordPress plugin globs that didn't convert properly but that can be cleaned up fairly easy.&lt;/p&gt;
&lt;p&gt;At this point it's time to customize the configurations, theme and plugins.&lt;/p&gt;
&lt;p&gt;The Pelican configuration file is in the root of the project folder named &lt;code&gt;pelicanconf.py&lt;/code&gt;. Here is were the defualts, themes, plugins and other conf8guration variables are set. &lt;/p&gt;
&lt;p&gt;The &lt;code&gt;pelican-quickstart&lt;/code&gt; app pre populates a few of the defaults like AUTHOR and SITENAME.&lt;/p&gt;
&lt;p&gt;To get started using plugins you will need to first clone the pelican-plugins repo. I set this up in the parent directory to the project.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git clone https://github.com/getpelican/pelican-plugins.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then add the following two variables to &lt;code&gt;pelicanconf.py&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# Plugins
PLUGIN_PATHS = [&amp;#39;../pelican-plugins&amp;#39;]
PLUGINS = [
    &amp;#39;assets&amp;#39;,
    &amp;#39;gzip_cache&amp;#39;,
    ...
]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There are a lot of plugins for Pelican and if you cant find what you are looking for it is not to hard to modify or write a plugin.&lt;/p&gt;
&lt;p&gt;Last part is picking a theme. A large list of themes can be found at http://www.pelicanthemes.com and the full repository of themes can be found on github 
https://github.com/getpelican/pelican-themes&lt;/p&gt;
&lt;p&gt;Pelican provides &lt;code&gt;pelican-themes&lt;/code&gt; a cli tool to help a user manage installed themes but it is not required to use the cli. You can also provide the path directly to the theme.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;THEME=&amp;quot;/path/to/theme&amp;quot;
# or
THEME=&amp;quot;&amp;lt;name&amp;gt;&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To get a list of installed themes &lt;code&gt;pelican-themes -l&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;More configuration variables can be found in the Pelican docs.&lt;/p&gt;
&lt;p&gt;That completes the migration last thing to do is push The new site out to production by uploading the generated content in &lt;code&gt;output&lt;/code&gt; or building it into a docker image. Here is a quick and easy &lt;code&gt;Dockerfile&lt;/code&gt; to build a Pelican site into a Nginx image.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;FROM nginx:alpine
RUN apk update &amp;amp;&amp;amp; \                                                                   apk upgrade
COPY ./output /usr/share/nginx/html
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Combine that with this &lt;code&gt;docker-compose.yml&lt;/code&gt; and you get a quick dev deployment.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;version: &amp;#39;3.4&amp;#39;
services:
    codeholics:
        container_name: codeholics_static
        build:               
          context: ..
        dockerfile: docker/Dockerfile
        image: codeholics/codeholics_static
        ports:
          - &amp;quot;8080:80&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To build the image:&lt;br&gt;
&lt;code&gt;docker-compose -f docker-compose.yml build&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Run the service:&lt;br&gt;
&lt;code&gt;docker-compose -f docker-compose.yml up&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Deploy on a swarm:&lt;br&gt;
&lt;code&gt;docker stack deploy -c docker-compose.yml codeholics&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Hope everyone enjoys the new site and content that follow.&lt;/p&gt;
&lt;p&gt;Happy Hacking!&lt;/p&gt;</content><category term="Coding"></category><category term="coding"></category><category term="python"></category><category term="docker"></category><category term="wordpress"></category><category term="pelican"></category></entry><entry><title>Python: working with X.509</title><link href="https://codeholics.com/python-working-with-x509.html" rel="alternate"></link><published>2019-02-21T07:30:00-05:00</published><updated>2021-02-19T07:39:00-05:00</updated><author><name>vesc</name></author><id>tag:codeholics.com,2019-02-21:/python-working-with-x509.html</id><summary type="html">&lt;h3 id="intro"&gt;Intro&lt;/h3&gt;
&lt;p&gt;This is a note dump of working with x509 in Python. There is not much context to it&lt;br&gt;
just a dump of code snippets.  &lt;/p&gt;
&lt;h3 id="needed-packages"&gt;Needed Packages:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;pyopenssl&lt;/li&gt;
&lt;li&gt;cryptography&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="generating-a-rsa-private-key"&gt;Generating a RSA Private Key:&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;datetime&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cryptography&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;x509&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cryptography.hazmat.backends&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;default_backend&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cryptography.hazmat.primitives …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;h3 id="intro"&gt;Intro&lt;/h3&gt;
&lt;p&gt;This is a note dump of working with x509 in Python. There is not much context to it&lt;br&gt;
just a dump of code snippets.  &lt;/p&gt;
&lt;h3 id="needed-packages"&gt;Needed Packages:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;pyopenssl&lt;/li&gt;
&lt;li&gt;cryptography&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="generating-a-rsa-private-key"&gt;Generating a RSA Private Key:&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;datetime&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cryptography&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;x509&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cryptography.hazmat.backends&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;default_backend&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cryptography.hazmat.primitives&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;hashes&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cryptography.hazmat.primitives.asymmetric&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;rsa&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cryptography.x509.oid&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;NameOID&lt;/span&gt;

&lt;span class="c1"&gt;# Generate RSA Key Pair&lt;/span&gt;
&lt;span class="n"&gt;private_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;generate_private_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;public_exponent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;65537&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;key_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2048&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;backend&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;default_backend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Get RSA Public Key&lt;/span&gt;
&lt;span class="n"&gt;public_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="generate-x509-self-signed-certificate"&gt;Generate x509 Self Signed Certificate:&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Build x509 Cert&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CertificateBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subject_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NameAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NameOID&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;COMMON_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;yoururl.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;issuer_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NameAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NameOID&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;COMMON_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;yoururl.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;not_valid_before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;today&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;one_day&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Today + 30 days&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;not_valid_after&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;today&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;one_day&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;serial_number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random_serial_number&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_extension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SubjectAlternativeName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DNSName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;yoururl.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;critical&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_extension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BasicConstraints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ca&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;critical&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Export Self Signed Cert&lt;/span&gt;
&lt;span class="n"&gt;certificate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;algorithm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;hashes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SHA256&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;backend&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;default_backend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="generate-x509-csr-certificate-signing-request"&gt;Generate x509 CSR (Certificate Signing Request):&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Build x509 CSR&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CertificateSigningRequestBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subject_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NameAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NameOID&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;COMMON_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;yoururl.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_extension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BasicConstraints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ca&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;critical&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hashes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SHA256&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;default_backend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="write-csr-to-a-file"&gt;Write CSR to a file:&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;yourname.csr&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;wb&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;csr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;csr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="looking-at-date-in-pem-certs"&gt;Looking at date in PEM certs:&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;OpenSSL.crypto&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FILETYPE_PEM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;load_certificate&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;pki_ca.pem&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;cert&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;         &lt;span class="n"&gt;pk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;load_certificate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FILETYPE_PEM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cert&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_notBefore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;20190212080550Z&amp;#39;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_notAfter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;20290209080620Z’&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_issuer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_components&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;CN&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;auto.localhost.local&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="load-private-key-pem-certificate-and-csr"&gt;Load Private Key, PEM Certificate and CSR:&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;OpenSSL.crypto&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="n"&gt;FILETYPE_PEM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;load_certificate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;load_certificate_request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;load_publickey&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Load CSR and others with the same style just use the proper loader&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mycsr.csr&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;csr_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;   &lt;span class="n"&gt;csr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;load_certificate_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FILETYPE_PEM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;csr_file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="check-signature-of-csr-certs"&gt;Check Signature of CSR certs:&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;test_pub.pem&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pem_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;   &lt;span class="n"&gt;pem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;load_certificate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FILETYPE_PEM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pem_file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;   &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_pubkey&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="kc"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="working-with-ca-crl"&gt;Working with CA CRL:&lt;/h3&gt;
&lt;p&gt;When working with Client SSL certificate verification one will run into the problem of creating a CRL PEM file of the&lt;br&gt;
Root CA's CRL file and its Intermediate CA's CRL files. This could come in a binary DER format that will need to be &lt;br&gt;
converted to PEM. Multiple PEM CRLs can be saved to a single concatenated file.  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Load DER format CRL&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cryptography&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;x509&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cryptography.hazmat.backends&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;default_backend&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/tmp/crl/DODSWCA_54.crl&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;br&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;crl_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;crl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load_der_x509_crl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;crl_file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;backend&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;default_backend&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="c1"&gt;# Cryptography &amp;gt;=3.4.5 you can omit the backend arg&lt;/span&gt;

&lt;span class="c1"&gt;# Save CRL Object as PEM format file&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cryptography.hazmat.primitives&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;serialization&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/tmp/crl/test.crl&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;wb&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;crl_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;crl_file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;crl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;public_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serialization&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encoding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PEM&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Python"></category><category term="coding"></category><category term="python"></category><category term="crypto"></category><category term="infosec"></category></entry><entry><title>How to Install libcouchbase on OpenSuse to use the Couchbase Python Module</title><link href="https://codeholics.com/how-to-install-libcouchbase-on-openSuse-to%20use-couchbase-python-module.html" rel="alternate"></link><published>2019-02-20T16:06:00-05:00</published><updated>2019-02-20T16:06:00-05:00</updated><author><name>vesc</name></author><id>tag:codeholics.com,2019-02-20:/how-to-install-libcouchbase-on-openSuse-to use-couchbase-python-module.html</id><summary type="html">&lt;p&gt;&lt;em&gt;OS:&lt;/em&gt; OpenSuse Tumbleweed&lt;/p&gt;
&lt;p&gt;Here are the steps to get libcouchbase installed on OpenSuse:&lt;/p&gt;
&lt;h3 id="get-dependences"&gt;Get dependences:&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo zypper in libev-devel cmake openssl-devel
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="get-source"&gt;Get source:&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git clone https://github.com/couchbase/libcouchbase.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="run-config-and-build"&gt;Run config and build:&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cd libcouchbase
mkdir build
../cmake/configure
make
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="run-tests"&gt;Run tests:&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cmake
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="install"&gt;Install:&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo make install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="load-newly-installed-libcouchbase-shared-objects"&gt;Load …&lt;/h3&gt;</summary><content type="html">&lt;p&gt;&lt;em&gt;OS:&lt;/em&gt; OpenSuse Tumbleweed&lt;/p&gt;
&lt;p&gt;Here are the steps to get libcouchbase installed on OpenSuse:&lt;/p&gt;
&lt;h3 id="get-dependences"&gt;Get dependences:&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo zypper in libev-devel cmake openssl-devel
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="get-source"&gt;Get source:&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git clone https://github.com/couchbase/libcouchbase.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="run-config-and-build"&gt;Run config and build:&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cd libcouchbase
mkdir build
../cmake/configure
make
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="run-tests"&gt;Run tests:&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cmake
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="install"&gt;Install:&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo make install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="load-newly-installed-libcouchbase-shared-objects"&gt;Load newly installed libcouchbase shared objects:&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ldconfig -v
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="install-couchbase-python-module"&gt;Install Couchbase Python Module:&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip install coucbase
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Linux"></category><category term="os"></category><category term="coding"></category><category term="python"></category><category term="couchbase"></category><category term="dev"></category><category term="linux"></category><category term="opensuse"></category></entry><entry><title>Displaylink DK1522 Issue after OpenSUSE Leap 42.3 Upgrade</title><link href="https://codeholics.com/displaylink-dk1522-issue-after-opensuse-leap-42-3-upgrade.html" rel="alternate"></link><published>2017-12-20T15:19:00-05:00</published><updated>2017-12-20T15:19:00-05:00</updated><author><name>vesc</name></author><id>tag:codeholics.com,2017-12-20:/displaylink-dk1522-issue-after-opensuse-leap-42-3-upgrade.html</id><summary type="html">&lt;p&gt;It is the end of the year and the time I use to upgrade my Lenovo P50 to the latest OpenSUSE Leap version. I do it this time of year because I expect to have some issue that I will need to work through after the upgrade and since this …&lt;/p&gt;</summary><content type="html">&lt;p&gt;It is the end of the year and the time I use to upgrade my Lenovo P50 to the latest OpenSUSE Leap version. I do it this time of year because I expect to have some issue that I will need to work through after the upgrade and since this is my work machine I pick a time of year when the office is quite and all the major projects are completed for the year.&lt;/p&gt;
&lt;p&gt;I am not going to go over the upgrade process as this is well covered in the OpenSuse documentation and other posts. The upgrade from 42.2 to 42.3 was in fact fairly smooth. The things that I expect to have problems with are the Displaylink DK1522 dock since it was a fairly involved process to get it running in the first place since they only officially support Ubuntu and the Nvidia display driver. Once the upgrade was completed and the dust settled. I plugged in my Displaylink DK1522 and hit 'Meta+D' the shortcut I have mapped to run a shell script with the xrandr commands to setup the external displays. As I anticipated nothing happened and with that it was time to start digging. Looking over a few things I see the dlm service has errored out and there is some log errors.&lt;/p&gt;
&lt;p&gt;First thing I did was check the &lt;a href="http://www.displaylink.com/downloads/ubuntu" title="Displaylink"&gt;Displaylink&lt;/a&gt; site expecting a new version of the Linux drivers. I was running the 1.2.x version and they recently released 1.4. This was exciting because I was having some screen paint issues that were fairly annoying. After downloading their package if you are using anything other than Ubuntu you will need to make so&lt;br&gt;
adjustments to the displaylink-install.sh script. After unzipping the file unpack the displaylink-driver-1.4.210.run.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;./displaylink-driver-1.4.210.run --noexec --keep&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Then navigate to the displaylink-driver-1.4.210 file.&lt;/p&gt;
&lt;p&gt;Copy &lt;a href="https://pastebin.com/ADpYR2nd" title="displaylink-installer.patch"&gt;displaylink-installer.patch&lt;/a&gt; into a&lt;br&gt;
displaylink-installer.patch and apply the patch.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;patch displaylink-installer.sh displaylink-installer.patch&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Once this was done and I went to install it. I got an error when it was building the evdi module. I have filed a issue on github that also has the work around: &lt;a href="https://github.com/DisplayLink/evdi/issues/110" title="evdi-issue-110"&gt;evdi-issues-110&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To apply the fix to evdi copy the text from Github into a patch file evdi_fb.patch and extract the evdi-1.4.210-src.tar.gz package.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mkdir evdi
tar xzf evdi-1.4.210-src.tar.gz -C ./evdi
patch ./evdi/evdi_fb.c ./evdi_fb.patch
tar czf ./evdi-1.4.210-src.tar.gz -C ./evdi .
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once the change is made to the evdi package it should install as intended.&lt;/p&gt;
&lt;p&gt;After the module package was installed I hopefully plug in my displaylink and hit 'Meta+D'. Once more nothing happened. Looking at the logs I started seeing these type of errors:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;...
Dec 19 11:24:02 linux-olhs.suse kernel: evdi: disagrees about version of symbol drm_framebuffer_cleanup
Dec 19 11:24:02 linux-olhs.suse kernel: evdi: Unknown symbol drm_framebuffer_cleanup (err -22)
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I tried loading the module manually with modprobe evdi and got the following error.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;modprobe&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ERROR&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;could&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;insert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;evdi&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Invalid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;argument&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The 'dkms status' command showed everything was install properly&lt;/p&gt;
&lt;p&gt;After googling for hours and trying lots of non-solutions I noticed a similar log error for my nvidia driver. The lead me to try and reinstall the nvidia driver and it was erroring out. I went back to see if things had changed on the OpenSuse / NVidia driver front and to my delight there is now a NVidia supported OpenSUSE repo for OpenSUSE leap and Tumbleweed.&lt;/p&gt;
&lt;p&gt;NVidia drivers have been a thorn in my side for many years so I was excited to add the repo and zypp my problems away.&lt;br&gt;
Reading the steps lead me to the problem with the Displaylink driver:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo zypper rm drm-kmp-default
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After removing this package and install the new NVidia driver all my issues were resolved. With the new Displaylink driver I no longer have the screen refresh issues I had with the prior version.&lt;/p&gt;
&lt;p&gt;I also can not wait to use this nvidia repo on my tumbleweed desktop. This should make upgrades a lot less of a hassle. I hope this post helps anyone with a similar setup to mine who might be experiencing a similar issue.&lt;/p&gt;</content><category term="Linux"></category><category term="os"></category><category term="coding"></category><category term="C"></category><category term="Lenovo"></category><category term="Linux"></category><category term="OpenSUSE"></category><category term="patch"></category><category term="Shell"></category><category term="Upgrade"></category></entry><entry><title>Defcon1</title><link href="https://codeholics.com/defcon1.html" rel="alternate"></link><published>2017-10-09T13:41:00-04:00</published><updated>2017-10-09T13:41:00-04:00</updated><author><name>vesc</name></author><id>tag:codeholics.com,2017-10-09:/defcon1.html</id><summary type="html">&lt;blockquote&gt;
&lt;p&gt;If you have a backup and you never test that backup you do not have a backup. - Unknown&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I do not remember where I read this quote but it always resonated with me. Especially sense disaster recovery was one of my major responsibilities for a globally used web application. Much …&lt;/p&gt;</summary><content type="html">&lt;blockquote&gt;
&lt;p&gt;If you have a backup and you never test that backup you do not have a backup. - Unknown&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I do not remember where I read this quote but it always resonated with me. Especially sense disaster recovery was one of my major responsibilities for a globally used web application. Much like the mechanic with the broken car. I was a little less diligent adhering to this rule in my side projects.&lt;/p&gt;
&lt;p&gt;Codeholics is a small side project between a few friends with a passion for technology. We like to share some of the knowledge and lessons learned (good or bad) we encounter along the way. As such, we use shared hosting because it is affordable and WordPress because its a simple platform to share information with a lot of plugins. We had constant issues with our last shared hosting provider Webhostingpad.com. With no response to our constant borage of tickets trying to get our site back online after they preformed a server migration to our account we finally decided it was time to try someone else.&lt;/p&gt;
&lt;p&gt;We found a new home over at A2 Hosting and dumped and dropped all the databases from our Webhostingpad account. When we tried to restore the database to our new instance of Wordpress the instance would bottoming out. This lead to low level analysis of the table structure and the .sql dump file. Here is what we found:&lt;/p&gt;
&lt;p&gt;The table structure in the backed up database and the newly created database had some major and alarming differences.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;wp_posts - missing from backup&lt;/li&gt;
&lt;li&gt;wp_users - missing from backup&lt;/li&gt;
&lt;li&gt;assortment of extra tables created by plugs littered the old database&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At this point I am grepping and scouring the .sql file for anything that might resemble post data. The thought was maybe one of these plugins moved the data into one of these random tables but it was no where to be found.&lt;/p&gt;
&lt;p&gt;Now I am freaking out because to the fault of my own I wrote the post directly into Wordpress and lived in blissful ignorance until it was to late.&lt;/p&gt;
&lt;p&gt;Right before passing out for the night with that pit in my stomach that all System Administrators know and hate of just getting caught with your pants down. I had a sudden idea: What if we check Archive.org to see if it has the site cached in the WayBackMachine. I grabbed my tablet that I keep next to my bed and started searching and seen they had a archive from April 30, 2016. This was older and we would lose a few posts but it was better than losing it all.&lt;/p&gt;
&lt;p&gt;The next day I saved one of the posts and started examining it for the HTML tags that held the post content.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;entry-title&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; - has the post title
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;td-post-content&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; - has the body of the post 
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;time&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;enctry-date update td-module-date&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; - had the post time stamp
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;link&lt;/span&gt; &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;canonical&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; - this had the post permalink title
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;At this point I had already decided I would not mind download the files by hand to see what was available but I was not willing to do all the rebuilding of the database by hand. This part of the job I would do with Python. The packages I used would be as follows:&lt;/p&gt;
&lt;p&gt;Python:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Beautifulsoup - parse the HTML files&lt;/li&gt;
&lt;li&gt;SQLAlchemy - to create a object relational map (ORM) between python and the MySQL database.&lt;/li&gt;
&lt;li&gt;mysqlclient - client used by SQLAlchemy for mysql.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;System:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;libmysqlclient-devel - dependency of mysqlclient python package&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The wordpress wp_posts table structure is as follows:&lt;/p&gt;
&lt;p&gt;Field                     Type                  Null   Key   Default               Extra&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;ID                        bigint(20) unsigned   NO     PRI   NULL                  auto_increment
  post_author              bigint(20) unsigned   NO     MUL   0                   &lt;br&gt;
  post_date                datetime              NO           0000-00-00 00:00:00 &lt;br&gt;
  post_date_gmt           datetime              NO           0000-00-00 00:00:00 &lt;br&gt;
  post_content             longtext              NO           NULL                &lt;br&gt;
  post_title               text                  NO           NULL                &lt;br&gt;
  post_excerpt             text                  NO           NULL                &lt;br&gt;
  post_status              varchar(20)           NO           publish             &lt;br&gt;
  comment_status           varchar(20)           NO           open                &lt;br&gt;
  ping_status              varchar(20)           NO           open                &lt;br&gt;
  post_password            varchar(255)          NO                               &lt;br&gt;
  post_name                varchar(200)          NO     MUL                       &lt;br&gt;
  to_ping                  text                  NO           NULL                &lt;br&gt;
  pinged                    text                  NO           NULL                &lt;br&gt;
  post_modified            datetime              NO           0000-00-00 00:00:00 &lt;br&gt;
  post_modified_gmt       datetime              NO           0000-00-00 00:00:00 &lt;br&gt;
  post_content_filtered   longtext              NO           NULL                &lt;br&gt;
  post_parent              bigint(20) unsigned   NO     MUL   0                   &lt;br&gt;
  guid                      varchar(255)          NO                               &lt;br&gt;
  menu_order               int(11)               NO           0                   &lt;br&gt;
  post_type                varchar(20)           NO     MUL   post                &lt;br&gt;
  post_mime_type          varchar(100)          NO                               &lt;br&gt;
  comment_count            bigint(20)            NO           0                     &lt;/p&gt;
&lt;p&gt;My SQLAlchemy class to wrap this table:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;Base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;declarative_base&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;#Post Object&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;&amp;#39;&amp;#39;&amp;#39;wpcp_posts table schema object&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
    &lt;span class="n"&gt;__tablename__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;wp_posts&amp;#39;&lt;/span&gt;

    &lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BigInteger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;post_author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BigInteger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;post_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;0000-00-00 00:00:00&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;post_date_gmt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;0000-00-00 00:00:00&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;post_content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;post_title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;post_excerpt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;post_status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;publish&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;comment_status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;open&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ping_status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;open&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;post_password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;post_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;to_ping&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;pinged&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;post_modified&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;0000-00-00 00:00:00&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="n"&gt;post_modified_gmt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;0000-00-00 00:00:00&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;post_content_filtered&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;post_parent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BigInteger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;guid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;menu_order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;post_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;post&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;post_mime_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;comment_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BigInteger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__repr__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;lt;Post(post_author=&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39;, post_date=&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39;, post_date_gmt=&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39;,   &lt;/span&gt;
               &lt;span class="n"&gt;post_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;post_title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;post_excerpt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;post_status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   
               &lt;span class="n"&gt;comment_status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ping_status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;post_password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;post_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   
               &lt;span class="n"&gt;to_ping&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pinged&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;post_modified&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;post_modified_gmt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   
               &lt;span class="n"&gt;post_content_filtered&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;post_parent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;guid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;menu_order&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;   
               &lt;span class="n"&gt;post_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;post_mime_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;comment_count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot; %   &lt;/span&gt;
               &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post_author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post_date_gmt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post_content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post_title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post_excerpt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post_status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;comment_status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ping_status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post_password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_ping&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pinged&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post_modified&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post_modified_gmt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post_content_filtered&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post_parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;guid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;menu_order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post_mime_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;comment_count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now that I had my ORM to the database. I just needed to write a little code to look at each of the .html files in a path and grab the good stuff from them with beautifulsoup&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="c1"&gt;# list path html files and import them&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;html_page&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scandir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Beautiful Soup Setup (open html page)&lt;/span&gt;
        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abspath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;html_page&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BeautifulSoup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;html.parser&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Title&lt;/span&gt;
        &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;h1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;class&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;entry-title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="c1"&gt;# Permalink&lt;/span&gt;
        &lt;span class="n"&gt;post_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;link&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;rel&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;canonical&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;})[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;href&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="c1"&gt;# post timestamp&lt;/span&gt;
        &lt;span class="n"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strptime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;time&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;datetime&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                                     &lt;span class="s1"&gt;&amp;#39;%Y-%m-&lt;/span&gt;&lt;span class="si"&gt;%d&lt;/span&gt;&lt;span class="s1"&gt;T%H:%M:%S+00:00&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# build content from p tags in td-post-conent&lt;/span&gt;
        &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;div&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;class&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;td-post-content&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;p&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prettify&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once all the content that was needed was stripped from the HTML pages. I created an post object and inserted it back into the database.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post_title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;post_author&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;post_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;post_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;post_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;post_date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;post_date_gmt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# insert into database&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;db_conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;db_conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once I had these components I ran the script on the fold with the .html files. After it completed I took a dump of the local mysql Wordpress database and uploaded it into devel to check the results.&lt;/p&gt;
&lt;p&gt;The full Python script can be viewed &lt;a href="https://github.com/Codeholics/archive_recovery" title="Archive Recovery"&gt;here&lt;/a&gt; on our github.&lt;/p&gt;
&lt;p&gt;I have always said I have learned more from the things that have broke than the things that worked and this was no exception. I had been wanting to use these Python packages for sometime and this gave me the need to use them. I also want to give a shout out to Internet Archive at archive.org. Without their amazing work all would have been lost. I encurage people to donate to archive.org as I will be as a 'thank you for saving my ass'.&lt;/p&gt;
&lt;h2 id="links"&gt;Links:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://archive.org/" title="archive.org"&gt;Internet Archive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://archive.org/donate" title="archive.org"&gt;Donate to the Internet Archive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://archive.org/web" title="waybackmachine"&gt;WayBackMachine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/" title="BeuatifulSoup"&gt;BeautifulSoup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.sqlalchemy.org/" title="SQLAlchemy"&gt;SQLAlchemy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Coding"></category><category term="coding"></category><category term="mysql"></category><category term="python"></category><category term="sqlalchemy"></category><category term="sysadmin"></category><category term="wordpress"></category></entry><entry><title>Codeholics is currently undergoing redevelopment</title><link href="https://codeholics.com/test-page-2.html" rel="alternate"></link><published>2017-04-29T04:04:00-04:00</published><updated>2017-04-29T04:04:00-04:00</updated><author><name>root</name></author><id>tag:codeholics.com,2017-04-29:/test-page-2.html</id><summary type="html">&lt;p&gt;Devel - We had to leave our old hosting provider "Webhostingpad" due to their system stability and service quality. Our new host has better hardware, bandwidth, security, and a stronger commitment to taking care of their customers.&lt;/p&gt;
&lt;p&gt;We initially went offline due to a technical issue on webhostingpads side after they …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Devel - We had to leave our old hosting provider "Webhostingpad" due to their system stability and service quality. Our new host has better hardware, bandwidth, security, and a stronger commitment to taking care of their customers.&lt;/p&gt;
&lt;p&gt;We initially went offline due to a technical issue on webhostingpads side after they moved our domain to another server. We tried to work with their support staff for weeks which they kept telling us it was something that was not part of the problem. After weeks of downtime and lack of the support staff responding or following up was so nerve racking to the point we closed our account with them after being a customer for well over 10 years.&lt;/p&gt;
&lt;p&gt;We then tried to restore the site but was unsuccessful due to plugins messing up our database tables to the point of no recovery. We're currently exercising our very last DR plan, however, this process will take a while. Please make sure to stop by and check in time to time or follow us on facebook for the new site launch. While we're working on the rebuild you're welcome to look around, just know your experience may not be optimal.&lt;/p&gt;
&lt;p&gt;Thank you,&lt;br&gt;
TheBleak&lt;/p&gt;</content><category term="misc"></category></entry><entry><title>The Poor Mans DynamicDNS</title><link href="https://codeholics.com/the-poor-mans-dynamicdns.html" rel="alternate"></link><published>2016-04-14T19:57:00-04:00</published><updated>2016-04-14T19:57:00-04:00</updated><author><name>root</name></author><id>tag:codeholics.com,2016-04-14:/the-poor-mans-dynamicdns.html</id><summary type="html">&lt;p&gt;A few years ago I had an issue where I needed a DynamicDNS service or some sort. I didnt want to pay for it and got the thought in my head to just write my own script that suited my need. The things it needed to do was check if …&lt;/p&gt;</summary><content type="html">&lt;p&gt;A few years ago I had an issue where I needed a DynamicDNS service or some sort. I didnt want to pay for it and got the thought in my head to just write my own script that suited my need. The things it needed to do was check if public IP had changed and send that change to me in some way so I could update my host file on my laptop. Fairly simple but effective to make sure I always knew how to phone home. I wrote a quick hacky python script to get the job done and it has been working for me for a few years now flawlessly.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/Codeholics/ipchecker"&gt;Click here&lt;/a&gt;&lt;br&gt;
to go to the Github repo&lt;/p&gt;
&lt;p&gt;Install:&lt;/p&gt;
&lt;p&gt;first figure out where you would like script to live and run:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git clone https://github.com/Codeholics/ipchecker&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Then edit ipchecker.py with your favorite text editor and add your info to the vars:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;#IP File&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;

&lt;span class="n"&gt;FILE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dat&lt;/span&gt; &lt;span class="c1"&gt;#File where it stores your IP to compare to&lt;/span&gt;

&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;#SMTP Options&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;

&lt;span class="n"&gt;EMAIL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt;&lt;span class="nd"&gt;@email&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;SMTPHOST&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;localhost&lt;/span&gt;
&lt;span class="n"&gt;SENDER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="nd"&gt;@email&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once this is done create a cron job in &lt;code&gt;/etc/cron.d/&lt;/code&gt; with the following schedule it however you would like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Check&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;current&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;an&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;has&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;changed&lt;/span&gt;

&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ipcheck&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The only issue with this is it will get filtered by any spam filter when it is sent from a residential dynamic IP address. You will need to mark it as not being spam or if you notice you cant get into your system check your spam folder.&lt;/p&gt;
&lt;p&gt;The script queries a site with curl that returns your public IP address then it checks that IP with the one inside the ip.dat file. If it is different than it emails out the new IP address and writes the new address to the ip.dat file.&lt;/p&gt;
&lt;p&gt;Enjoy&lt;/p&gt;</content><category term="Coding"></category><category term="coding"></category><category term="shell"></category><category term="os"></category><category term="linux"></category><category term="python"></category></entry><entry><title>Book Review: The Phoenix Project</title><link href="https://codeholics.com/book-review-the-phoenix-project.html" rel="alternate"></link><published>2016-04-07T22:25:00-04:00</published><updated>2016-04-07T22:25:00-04:00</updated><author><name>root</name></author><id>tag:codeholics.com,2016-04-07:/book-review-the-phoenix-project.html</id><summary type="html">&lt;p&gt;&lt;em&gt;Note I:&lt;/em&gt;&lt;br&gt;
So this is finally the beginning of this review, and in the interest of full disclosure Ive been sitting on this review for a long time, longer than I really should have, but writing a review of this book actually seems a little daunting.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note II:&lt;/em&gt;&lt;br&gt;
As this …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;em&gt;Note I:&lt;/em&gt;&lt;br&gt;
So this is finally the beginning of this review, and in the interest of full disclosure Ive been sitting on this review for a long time, longer than I really should have, but writing a review of this book actually seems a little daunting.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note II:&lt;/em&gt;&lt;br&gt;
As this book is a narrative, the review will have some spoilers&lt;/p&gt;
&lt;p&gt;The Phoenix Project is a book that anyone who works in Software Development should read.  And when I say anyone, I mean ANYONE.  Product Owners, Project Managers, IT, Developers, QA all levels of development.  The book tries to do the impossible, and bring to light the answer to the quote ITs work for deployment is invisible p.253&lt;/p&gt;
&lt;p&gt;***SPOILER filled review starts HERE***&lt;/p&gt;
&lt;p&gt;Book starts with a company which has got a major, over-budgeted, overdue, full of bugs, project that needs to go out the door and save the company.  And the main, Bill Palmer, just got promoted to VP of IT Operations, and inherited the crap-shoot of a project.&lt;/p&gt;
&lt;p&gt;As the book progresses, problems are brought to light that leads the main character to develop processes and rigors to overcome the problems.  And along with these new processes and rigors, the reader is brought along the thought process of course correcting and fixing not just your product but actually also your process.&lt;/p&gt;
&lt;p&gt;I will digress here and say as the reviewer, I feel obligated to reveal to you, the reader, that I have a long background with Software QA, and during my career as a QA person, the one thing that guided how I approached any of my positions was this one goal, QA the product, QA the process.  No process is perfect for the team or the work at the time, so constant review of the process is definitely necessary.  Now back to the book.  &lt;/p&gt;
&lt;p&gt;Throughout the book, key knowledge drops  were abound.  Fun quotes like the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Your problem right now is that you obviously dont actually know what work is  &lt;/p&gt;
&lt;p&gt;Eliyahu M. Goldratt, . any improvements made anywhere besides the bottleneck are an illusion.  &lt;/p&gt;
&lt;p&gt;Preventative work supports the company  &lt;/p&gt;
&lt;p&gt;Until code is in production, no value is generated.  &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Anyone whos worked in the software industry already knows a lot of this stuff, and have probably already implemented some of the solutions to the common problems.  However, the book is rife with as many different challenges as possible, which is why I believe this book is worth reading, even if youve been in the industry for 50 years.&lt;/p&gt;
&lt;p&gt;But theres an answer that I was looking for, that this book doesnt provide.  And that is the only place where I feel the book is lacking.&lt;/p&gt;
&lt;p&gt;The people in the book, all its characters, are supposed to be the avatars for their respective departments (QA, Internal Audit, Dev, Product Owner, CEO, etc etc)  At the beginning of the book, even through the first 70 pages, conflict exists across all teams, with finger pointing and blaming everywhere.  Even the CEO was throwing fingers and blaming in a ready, SHOOT, aim fashion.&lt;/p&gt;
&lt;p&gt;It is because of these conflicts that I read through the book.  The other knowledge pearls were a plus, but I was looking for an answer; something to help me and my team get better at interacting with each other.  You see, the left overs from the Waterfall process, are the items where people point fingers based on responsibilities.  And there has to be a way to help with that transition process from Waterfall to Agile, without just first getting rid of people who were still mentally Waterfall.&lt;/p&gt;
&lt;p&gt;It can be said that, without teamwork, none of these solutions and knowledge pearls can be achieved and the book never answers how the teams can get in alignment its here where the book waves the proverbial Hand of God.&lt;/p&gt;
&lt;p&gt;Is the book worth reading?  DEFINITELY.&lt;/p&gt;
&lt;p&gt;Is it the ONLY book worth reading?  definitely NOT.&lt;/p&gt;
&lt;p&gt;So please do yourselves the favor, buy the book, read the book, and gain all the knowledge pearls the book offers, because at the end of the day, this book really does provide a whole crap ton of them.&lt;/p&gt;
&lt;p&gt;Buy on Amazon:&lt;/p&gt;
&lt;p&gt;http://www.amazon.com/Phoenix-Project-DevOps-Helping-Business/dp/0988262509&lt;/p&gt;</content><category term="Book Review"></category><category term="review"></category><category term="book review"></category></entry><entry><title>Understanding Linux Basic Disk Partition Setup</title><link href="https://codeholics.com/understanding-linux-basic-disk-partition-setup.html" rel="alternate"></link><published>2016-03-25T11:30:00-04:00</published><updated>2016-03-25T11:30:00-04:00</updated><author><name>root</name></author><id>tag:codeholics.com,2016-03-25:/understanding-linux-basic-disk-partition-setup.html</id><summary type="html">&lt;p&gt;Recently I was asked the question what are the needed Linux partitions and what are they for? With that I thought it would be a good post because this is something that is very overlooked since distro installs have become so simple most people just go with the defaults, but …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Recently I was asked the question what are the needed Linux partitions and what are they for? With that I thought it would be a good post because this is something that is very overlooked since distro installs have become so simple most people just go with the defaults, but as always it is important to know what is going on under the hood. I will go over a minimal disk configuration and with a minimal disk configuration you only need three partitions.&lt;/p&gt;
&lt;p&gt;The first and most important partition on any Linux disk layout is the &lt;em&gt;/boot&lt;/em&gt; partition.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;/boot&lt;/em&gt; partition holds your boot loader and boot loader configurations and Linux kernel images. This partition only needs to be about 300 to 400MB.&lt;/p&gt;
&lt;p&gt;The next partition would be your &lt;em&gt;swap&lt;/em&gt; partition. This is disk space the system will use under heavy memory usage. The &lt;em&gt;swap&lt;/em&gt; partition should very in size based upon your systems memory configuration. Here are some rules of thumb when configuring your &lt;em&gt;swap&lt;/em&gt; partition:&lt;/p&gt;
&lt;p&gt;The last partition in the list of minimum need partitions in a Linux system is the &lt;em&gt;/&lt;/em&gt; &lt;em&gt;root&lt;/em&gt; partition. The root partition should be the remained of your hard disk under a basic setup. This partition will have all your user and application files.&lt;/p&gt;
&lt;p&gt;This is by far this most simplistic setup of a disk on a Linux system and most automated configurations will do a more complicated setup of the disk using LVM (Logical Volume Manager) to manage the &lt;em&gt;/&lt;/em&gt; root and &lt;em&gt;swap&lt;/em&gt; partitions. In any configuration though under any file system type, manager or raid configuration the &lt;em&gt;/boot&lt;/em&gt;, &lt;em&gt;/&lt;/em&gt; and &lt;em&gt;swap&lt;/em&gt; partitions are still the minimum partitions needed for a Linux system.&lt;/p&gt;</content><category term="Linux"></category><category term="os"></category><category term="linux"></category><category term="tutorial"></category></entry><entry><title>Thirty years of Mac ads (1984-2014)</title><link href="https://codeholics.com/thirty-years-of-mac-ads-1984-2014.html" rel="alternate"></link><published>2016-03-05T11:00:00-05:00</published><updated>2016-03-05T11:00:00-05:00</updated><author><name>root</name></author><id>tag:codeholics.com,2016-03-05:/thirty-years-of-mac-ads-1984-2014.html</id><content type="html">&lt;p&gt;&lt;a
                    href="https://www.youtube.com/watch?v=Ytuznpy95ZU"
                class="youtube_video" alt="YouTube Video"
                title="Click to view on YouTube"
                target="_blank" rel="noopener noreferrer"&gt;
                    &lt;img width="640" height="480"
                        src="https://img.youtube.com/vi/Ytuznpy95ZU/sddefault.jpg"&gt;
                &lt;/a&gt;&lt;/p&gt;</content><category term="Video"></category><category term="hardware"></category><category term="apple"></category><category term="mac"></category><category term="video"></category></entry><entry><title>How to make a motherboard a GIGABYTE Factory Tour</title><link href="https://codeholics.com/how-to-make-a-motherboard-a-gigabyte-factory-tour.html" rel="alternate"></link><published>2016-03-04T13:02:00-05:00</published><updated>2016-03-04T13:02:00-05:00</updated><author><name>root</name></author><id>tag:codeholics.com,2016-03-04:/how-to-make-a-motherboard-a-gigabyte-factory-tour.html</id><content type="html">&lt;p&gt;How to make a motherboard a GIGABYTE Factory Tour&lt;br&gt;
&lt;a
                    href="https://www.youtube.com/watch?v=Va3Bfjn4inA"
                class="youtube_video" alt="YouTube Video"
                title="Click to view on YouTube"
                target="_blank" rel="noopener noreferrer"&gt;
                    &lt;img width="640" height="480"
                        src="https://img.youtube.com/vi/Va3Bfjn4inA/sddefault.jpg"&gt;
                &lt;/a&gt;&lt;/p&gt;</content><category term="Video"></category><category term="hardware"></category><category term="video"></category></entry><entry><title>How a CPU Works</title><link href="https://codeholics.com/how-a-cpu-works.html" rel="alternate"></link><published>2016-03-03T13:00:00-05:00</published><updated>2016-03-03T13:00:00-05:00</updated><author><name>root</name></author><id>tag:codeholics.com,2016-03-03:/how-a-cpu-works.html</id><content type="html">&lt;p&gt;How a CPU Works:
&lt;a
                    href="https://www.youtube.com/watch?v=cNN_tTXABUA"
                class="youtube_video" alt="YouTube Video"
                title="Click to view on YouTube"
                target="_blank" rel="noopener noreferrer"&gt;
                    &lt;img width="640" height="480"
                        src="https://img.youtube.com/vi/cNN_tTXABUA/sddefault.jpg"&gt;
                &lt;/a&gt;&lt;/p&gt;</content><category term="Video"></category><category term="cpu"></category><category term="hardware"></category><category term="video"></category></entry><entry><title>How Lexar Makes SD cards</title><link href="https://codeholics.com/how-we-make-sd-cards.html" rel="alternate"></link><published>2016-03-03T07:46:00-05:00</published><updated>2016-03-03T07:46:00-05:00</updated><author><name>root</name></author><id>tag:codeholics.com,2016-03-03:/how-we-make-sd-cards.html</id><content type="html">&lt;p&gt;&lt;a
                    href="https://www.youtube.com/watch?v=z_HSDp8KFfA"
                class="youtube_video" alt="YouTube Video"
                title="Click to view on YouTube"
                target="_blank" rel="noopener noreferrer"&gt;
                    &lt;img width="640" height="480"
                        src="https://img.youtube.com/vi/z_HSDp8KFfA/sddefault.jpg"&gt;
                &lt;/a&gt;&lt;/p&gt;</content><category term="Video"></category><category term="hardware"></category><category term="sd cards"></category><category term="video"></category></entry><entry><title>Get the exit code of a bash command</title><link href="https://codeholics.com/get-the-exit-code-of-a-bash-command.html" rel="alternate"></link><published>2016-02-25T16:00:00-05:00</published><updated>2016-02-25T16:00:00-05:00</updated><author><name>root</name></author><id>tag:codeholics.com,2016-02-25:/get-the-exit-code-of-a-bash-command.html</id><summary type="html">&lt;p&gt;If you want to see the exit status of a Linux shell command in bash use the variable&lt;br&gt;
&lt;code&gt;$?&lt;/code&gt;&lt;br&gt;
This will return the exit status of the last command.&lt;/p&gt;
&lt;p&gt;Now this will only give you the right most exit code if you are piping a command.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;~&amp;gt; ls | sort&lt;/code&gt;  &lt;/p&gt;
&lt;p&gt;the last command …&lt;/p&gt;</summary><content type="html">&lt;p&gt;If you want to see the exit status of a Linux shell command in bash use the variable&lt;br&gt;
&lt;code&gt;$?&lt;/code&gt;&lt;br&gt;
This will return the exit status of the last command.&lt;/p&gt;
&lt;p&gt;Now this will only give you the right most exit code if you are piping a command.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;~&amp;gt; ls | sort&lt;/code&gt;  &lt;/p&gt;
&lt;p&gt;the last command sort would be the exit code in&lt;br&gt;
&lt;code&gt;$?&lt;/code&gt;&lt;/p&gt;</content><category term="Linux"></category><category term="os"></category><category term="linux"></category><category term="sysadmin"></category><category term="bash"></category><category term="shell"></category></entry><entry><title>How To Reveal The Password Hidden Behind Asterisks</title><link href="https://codeholics.com/how-to-reveal-the-password-hidden-behind-asterisks.html" rel="alternate"></link><published>2016-02-19T11:00:00-05:00</published><updated>2016-02-19T11:00:00-05:00</updated><author><name>root</name></author><id>tag:codeholics.com,2016-02-19:/how-to-reveal-the-password-hidden-behind-asterisks.html</id><content type="html">&lt;p&gt;How To Reveal The Password Hidden Behind Asterisks: Google Chrome, Firefox and other browsers hide passwords behind asterisks but I will show you How to See your Passwords Hidden Under Asterisks field from password to text and hence the password is revealed as the text input.  &lt;/p&gt;
&lt;p&gt;&lt;a
                    href="https://www.youtube.com/watch?v=TeVQd0CTaQ8"
                class="youtube_video" alt="YouTube Video"
                title="Click to view on YouTube"
                target="_blank" rel="noopener noreferrer"&gt;
                    &lt;img width="640" height="480"
                        src="https://img.youtube.com/vi/TeVQd0CTaQ8/sddefault.jpg"&gt;
                &lt;/a&gt;&lt;/p&gt;</content><category term="Video"></category><category term="Hacking"></category><category term="Video"></category></entry><entry><title>Book Review: Ready Player One</title><link href="https://codeholics.com/book-review-ready-player-one.html" rel="alternate"></link><published>2016-02-18T19:14:00-05:00</published><updated>2016-02-18T19:14:00-05:00</updated><author><name>root</name></author><id>tag:codeholics.com,2016-02-18:/book-review-ready-player-one.html</id><summary type="html">&lt;p&gt;Book Series: Ready Player One  &lt;/p&gt;
&lt;p&gt;Author: Ernest Cline&lt;/p&gt;
&lt;p&gt;Once having heard this book being described as Willie Wonka meets World of Warcraft, the description seemed very attractive.  And in no way does the description not ring true.  Ernest Cline had a lot of fun writing this novel as he did …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Book Series: Ready Player One  &lt;/p&gt;
&lt;p&gt;Author: Ernest Cline&lt;/p&gt;
&lt;p&gt;Once having heard this book being described as Willie Wonka meets World of Warcraft, the description seemed very attractive.  And in no way does the description not ring true.  Ernest Cline had a lot of fun writing this novel as he did marketing it.&lt;/p&gt;
&lt;p&gt;Beyond the book, he even tied a three month Easter egg hunt to enhance the experience of reading the book. Readers of the first edition hard cover were treated with having to find a riddle in the book, answering it led to a website. At this website theyd have to beat a video game , then repeat all steps tree times. Ultimately at the end , the winning reader won a DeLorean with a built in flux capacitor.&lt;/p&gt;
&lt;p&gt;All of this ties to a novel that has the joys of an online video game adventure combined with a fun childish mystery.  At the beginning , readers will be introduced to a world where the eighties are everything and the people with the most knowledge will have the greatest advantage.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;And although the protagonist seems to be a character that might not seem worthy of the readers cheers at first, as the story picks up, theyll suddenly find themselves rooting for him out loud.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;This isnt meant to be the most believable book. Its requirement of disbelief extends as far as any Harry Potter and Lord of the Rings or Percy Jackson.  But beyond that disbelief, there are some references to the eighties that might be too obscure for some younger readers.  Those readers should be prepared to read along side the Internet, just in case the occasional Google search is required.&lt;/p&gt;
&lt;p&gt;To know if this book is for you, ask yourself the following.  Are you a person who likes rooting for people?  Have you watched shows like The Amazing Race, and liked it?  Do you like geeky nerdy 80s pop culture references?  Do you like video games? Do you root for the underdog?&lt;/p&gt;
&lt;p&gt;If youve said yes to any of those questions, this book is for you.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;BUY IT ON AMAZON!&lt;/p&gt;
&lt;p&gt;&lt;a href="https://web-beta.archive.org/web/20160302014637/http://www.amazon.com/Ready-Player-One-Ernest-Cline/dp/0307887448/"&gt;&lt;br&gt;
Ready Player One!&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;</content><category term="Book Review"></category><category term="review"></category><category term="book review"></category><category term="scifi"></category></entry><entry><title>Book Series: Zero Day + Trojan Horse</title><link href="https://codeholics.com/book-series-zero-day-trojan-horse.html" rel="alternate"></link><published>2016-02-10T17:13:00-05:00</published><updated>2016-02-10T17:13:00-05:00</updated><author><name>root</name></author><id>tag:codeholics.com,2016-02-10:/book-series-zero-day-trojan-horse.html</id><summary type="html">&lt;p&gt;&lt;img alt="TrojanHorse" src="https://web-beta.archive.org/web/20160227002708im_/https://codeholics.com/wp-content/uploads/TrojanHorse-200x300.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Book Series: Jeff Aiken series&lt;/p&gt;
&lt;p&gt;Author: Mark Russinovich&lt;/p&gt;
&lt;p&gt;Mark Russinovich has provided an immeasurable difference in the computing world.  As a co-founder of Windows Internals and now Microsoft Azure CTO, its hard to imagine that Mark has more to give. However with these two books, he once again has given …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="TrojanHorse" src="https://web-beta.archive.org/web/20160227002708im_/https://codeholics.com/wp-content/uploads/TrojanHorse-200x300.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Book Series: Jeff Aiken series&lt;/p&gt;
&lt;p&gt;Author: Mark Russinovich&lt;/p&gt;
&lt;p&gt;Mark Russinovich has provided an immeasurable difference in the computing world.  As a co-founder of Windows Internals and now Microsoft Azure CTO, its hard to imagine that Mark has more to give. However with these two books, he once again has given another positive to the people of this industry.&lt;/p&gt;
&lt;p&gt;It goes without saying that media and entertainment avenues struggle sometimes to compromise technological realism with entertainment, but Mark has provided a series that seems to be tailored specifically for the geek in all of us.&lt;/p&gt;
&lt;p&gt;Just like most thrillers both books get you with a hook, but Marks style follows up the flash with a slow burn.  The story simmers and gives the readers time to breathe and take in the technology.  Part of this pace is due to Marks none forgiving attention to detail.  Traditional thriller readers might get turned away, but techies will enjoy the extra information.&lt;/p&gt;
&lt;p&gt;The series follows a character named Jeff Aiken, who isnt your normal spy thriller character.  However, just like other information thrillers, such as the Dan Brown series Da Vinci Code and Angels and Demons, the lead character is intelligent on his feet, and makes nerds look good.&lt;/p&gt;
&lt;p&gt;Though, as a forewarning, the content in both books are definitely reliant on the technology at the time.  With Zero Day in 2011 and Trojan Horse published at 2012, the technology mentioned is definitely outdated by todays standards.  So if youre a super techie, youll have to keep that in mind.  However, this shouldnt ruin the books for you, as the books definitely live up to the thriller in techno-thriller.&lt;/p&gt;
&lt;p&gt;These books are a great pickup and a great pair of books as part of any techies library.&lt;/p&gt;
&lt;p&gt;Buy the books!&lt;/p&gt;
&lt;p&gt;&lt;a href="https://web-beta.archive.org/web/20160227002708/http://www.amazon.com/Zero-Day-Jeff-Aiken-Novel/dp/1250007305/"&gt;Zero Day&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://web-beta.archive.org/web/20160227002708/http://www.amazon.com/Trojan-Horse-Jeff-Aiken-Novel/dp/1250042542/"&gt;Trojan Horse&lt;/a&gt;&lt;/p&gt;</content><category term="Book Review"></category><category term="review"></category><category term="book review"></category></entry><entry><title>7 Gamers, 1 CPU Ultimate Virtualized Gaming Build Log</title><link href="https://codeholics.com/7-gamers-1-cpu-ultimate-virtualized-gaming-build-log.html" rel="alternate"></link><published>2016-02-03T19:41:00-05:00</published><updated>2016-02-03T19:41:00-05:00</updated><author><name>root</name></author><id>tag:codeholics.com,2016-02-03:/7-gamers-1-cpu-ultimate-virtualized-gaming-build-log.html</id><content type="html">&lt;p&gt;&lt;a
                    href="https://www.youtube.com/watch?v=LXOaCkbt4lI"
                class="youtube_video" alt="YouTube Video"
                title="Click to view on YouTube"
                target="_blank" rel="noopener noreferrer"&gt;
                    &lt;img width="640" height="480"
                        src="https://img.youtube.com/vi/LXOaCkbt4lI/sddefault.jpg"&gt;
                &lt;/a&gt;&lt;/p&gt;</content><category term="Video"></category><category term="gaming"></category><category term="hardware"></category><category term="video"></category></entry><entry><title>Book Review: Influx</title><link href="https://codeholics.com/influx.html" rel="alternate"></link><published>2016-02-03T05:33:00-05:00</published><updated>2016-02-03T05:33:00-05:00</updated><author><name>root</name></author><id>tag:codeholics.com,2016-02-03:/influx.html</id><summary type="html">&lt;p&gt;Book Series: Influx&lt;/p&gt;
&lt;p&gt;Author: Daniel Suarez&lt;/p&gt;
&lt;p&gt;Daniel Suarez has always had my interest with the technological thrillers that hes written. When I first was introduced to Daemon, it was an adventure that caused me to read the book in a very short period of time.&lt;/p&gt;
&lt;p&gt;In all his books, theres …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Book Series: Influx&lt;/p&gt;
&lt;p&gt;Author: Daniel Suarez&lt;/p&gt;
&lt;p&gt;Daniel Suarez has always had my interest with the technological thrillers that hes written. When I first was introduced to Daemon, it was an adventure that caused me to read the book in a very short period of time.&lt;/p&gt;
&lt;p&gt;In all his books, theres always been a hint of bleeding edge technology driving the story line, with humanity as a topic in tow.  And this book is no exception, however Arthur C. Clarkes third law seems to apply here.&lt;/p&gt;
&lt;p&gt;As a person reads this book, the first couple of chapters really sets up a situation where someone would have to take the information as a leap of faith.  The real story doesnt really occur until maybe 30% into the book.  This has deterred some people in the reviews, and I dont fully disagree with them.  But now that Ive read the whole book, I wouldnt really change a word.&lt;/p&gt;
&lt;p&gt;The use of magical science dictates the need for an explanation of the science, which means. a dry first 1/3 of the book.  The beginning really sets the book up to be more of a sci-fi novel than a thriller, but the key to this book is the turn and the finish.&lt;/p&gt;
&lt;p&gt;Unlike the beginning, the middle and end of the book is the rest of the roller coaster ride.  The book can, in no way, be described as anything other than a thriller.  And a fun one to boot.&lt;/p&gt;
&lt;p&gt;So my advice to anyone who starts to read Influx, start and push through.  And youll eventually feel drawn in, like gravity.&lt;/p&gt;
&lt;p&gt;Enjoy the ride.&lt;br&gt;
&lt;img alt=":-)" src="https://web-beta.archive.org/web/20160205022122im_/https://codeholics.com/wp-includes/images/smilies/simple-smile.png"&gt;&lt;/p&gt;
&lt;p&gt;Buy the book on&lt;br&gt;
&lt;a href="http://www.amazon.com/Influx-Daniel-Suarez/dp/0451469445/"&gt;Amazon!&lt;/a&gt;&lt;/p&gt;</content><category term="Review"></category><category term="review"></category><category term="book review"></category><category term="scifi"></category></entry><entry><title>LVM: Move a logical volume into a new volume group.</title><link href="https://codeholics.com/lvm-split-a-volume-group-into-a-new-volume-group.html" rel="alternate"></link><published>2016-01-22T08:23:00-05:00</published><updated>2016-01-22T08:23:00-05:00</updated><author><name>vesc</name></author><id>tag:codeholics.com,2016-01-22:/lvm-split-a-volume-group-into-a-new-volume-group.html</id><summary type="html">&lt;p&gt;&lt;em&gt;OS:&lt;/em&gt; &lt;em&gt;nix&lt;br&gt;
&lt;/em&gt;Require:&lt;em&gt; LVM, the power of root&lt;br&gt;
&lt;/em&gt;Skill Level:* Intermediate&lt;/p&gt;
&lt;p&gt;Here is how to move a logical volume into a new volume group in LVM using &lt;code&gt;vgsplit&lt;/code&gt;  &lt;/p&gt;
&lt;p&gt;Lets say you want to change the volume group settings for some of your logical volumes or you just want the logical …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;em&gt;OS:&lt;/em&gt; &lt;em&gt;nix&lt;br&gt;
&lt;/em&gt;Require:&lt;em&gt; LVM, the power of root&lt;br&gt;
&lt;/em&gt;Skill Level:* Intermediate&lt;/p&gt;
&lt;p&gt;Here is how to move a logical volume into a new volume group in LVM using &lt;code&gt;vgsplit&lt;/code&gt;  &lt;/p&gt;
&lt;p&gt;Lets say you want to change the volume group settings for some of your logical volumes or you just want the logical volumes better organized.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Use vgsplit to move your logical volume to its new volume group.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Check out your new volume group with the logical volume you moved:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Activate your logical volume and re mount it. Make sure to update the mapping in your fstab to the new volume group name that your logical volume resides under now.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go get coffee&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</content><category term="Linux"></category><category term="linux"></category><category term="sysadmin"></category></entry><entry><title>Getting Started with Metasploit in Kali Linux</title><link href="https://codeholics.com/getting-started-with-metasploit-in-kali-linux.html" rel="alternate"></link><published>2015-07-24T16:51:00-04:00</published><updated>2015-07-24T16:51:00-04:00</updated><author><name>root</name></author><id>tag:codeholics.com,2015-07-24:/getting-started-with-metasploit-in-kali-linux.html</id><summary type="html">&lt;p&gt;&lt;em&gt;OS:&lt;/em&gt; Kali Linux&lt;br&gt;
&lt;em&gt;Skill Level:&lt;/em&gt; Intermediate&lt;br&gt;
&lt;em&gt;Prerequisites:&lt;/em&gt; Linux CLI, Basic Networking Concepts, PostgresSQL&lt;/p&gt;
&lt;p&gt;Metasploit is the closet thing to push button security and penetration testing one can find. It is by far the most popular security testing framework. Metasploit has thousands of modules and is growing daily with a very …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;em&gt;OS:&lt;/em&gt; Kali Linux&lt;br&gt;
&lt;em&gt;Skill Level:&lt;/em&gt; Intermediate&lt;br&gt;
&lt;em&gt;Prerequisites:&lt;/em&gt; Linux CLI, Basic Networking Concepts, PostgresSQL&lt;/p&gt;
&lt;p&gt;Metasploit is the closet thing to push button security and penetration testing one can find. It is by far the most popular security testing framework. Metasploit has thousands of modules and is growing daily with a very active community getting modules for exploits out not long after they have been reported. The framwork is written in Ruby so, if that is your language of choice you might want to join in on the action. No InfoSec teams tool kit should be without this tool when trying to keep the castle walls strong against would be attackers. Since it is open source and widely available in most Linux distros you can bet someone might try or be trying some of these modules against your network and systems as you read this.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Real life use case:&lt;/em&gt;&lt;br&gt;
I was able to identify and finger print a DOS (Denial of Service) attack and find a module in Metasploit to replicate the attack and help an InfoSec and Network Team strengthen the configuration of the IPS (Intrusion Prevention System) and block out attacks of this type. Later on I will come back with a post about (D)DOS attacks and preventative measures. Lets get started with setting up Metasploit with a PostrgesSQL database in Kali Linux.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;First of install kali linux we assume you got that covered.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open a command prompt and type (as root or with sudo):
&lt;code&gt;# service postgressql start&lt;/code&gt;&lt;br&gt;
this will bring up the postgres database&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Bring up the metaspoit service&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Since this is your first time running it. It will detect that postgres is running and set up the Metaspoit database.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Now its time to play and run the Metasploit console&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now lets get started with understanding workspaces. Workspaces help separate testing information.&lt;/p&gt;
&lt;p&gt;to see all the options for the &lt;code&gt;workspace&lt;/code&gt;
command:&lt;/p&gt;
&lt;p&gt;Lets add a workspace:&lt;/p&gt;
&lt;p&gt;now if you type &lt;code&gt;workspace&lt;/code&gt; you can see you are using the test1 workspace instead of default.&lt;/p&gt;
&lt;p&gt;the first step of security tests is reconnaissance to gather information about a system or environment. We can do this using nmap. Nmap is a port scanning tool that can identify services running on a system and try to figure out the operating system running on that system. Metasploit has nmap built in and can add the results straight to the workspaces database so the results can be easily filter through to find systems with services that you want to test with a specific module. The nmap module is call&lt;br&gt;
&lt;code&gt;db_nmap&lt;/code&gt; 
and you can pass it all the same commands you would when using nmap outside of the metasploit framework.&lt;/p&gt;
&lt;p&gt;Nmap will do its thing and now you will have that information in your database.&lt;/p&gt;
&lt;p&gt;to look at the information we have gathered  use the hosts and services commands.&lt;/p&gt;
&lt;p&gt;hosts: Shows all host information like DNS name and OS type.&lt;/p&gt;
&lt;p&gt;services: Shows all running services the port scan picked up and what service they might be.&lt;/p&gt;
&lt;p&gt;As with all commands you can pass them the &lt;code&gt;-h&lt;/code&gt;
and get help information. The most helpful I found was filtering services out by port number and adding them to the &lt;code&gt;RHOST&lt;/code&gt; global variable.&lt;/p&gt;
&lt;p&gt;This will add all hosts that have a service running on port 80 to the &lt;code&gt;RHOST&lt;/code&gt; global variable. This is most likely a web server because port 80 is the standard HTTP port. We can check the variable values by using the set commands this is also used as you might have guessed to set a variables value:&lt;/p&gt;
&lt;p&gt;This is important for setting up variables for modules to run.&lt;/p&gt;
&lt;p&gt;To select a module to use we type
&lt;code&gt;use [module]&lt;/code&gt;. Module are broken up in categories such as auxilary then broken down further from there. I guess I can not leave this hanging without running a module against our RHOST that we set, so lets run the module that helped ID the attack in the beginning of this post.&lt;/p&gt;
&lt;p&gt;check the variables with set but we should be good to run at this point since we have a host running a web server. If you go to run it and get and error it is probably do to the interface not being set correctly. If you are on wireless use:&lt;/p&gt;
&lt;p&gt;now exploit:&lt;/p&gt;
&lt;p&gt;It should start sending a synflood to the host you have selected. Since you are doing this to a lab system or a system you own (disclaimer :-)). Log on and check the activity with netstat -t you should see a bunch of this:&lt;/p&gt;
&lt;p&gt;Now if this was behind a properly configured IPS or IDS it would get blocked, alert the interested parties and service would continue with normal users not noticing anything. Now go have some fun with the other module and make sure the walls are strong and systems are secure. I will try to cover some more modules later as I go deeper into web application security.&lt;/p&gt;
&lt;p&gt;Links:&lt;br&gt;
&lt;a href="https://www.kali.org/"&gt;https://www.kali.org/&lt;/a&gt;Kali Linux  &lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.metasploit.com/"&gt;https://www.metasploit.com/&lt;/a&gt;Metasploit&lt;/p&gt;</content><category term="Linux"></category><category term="infosec"></category><category term="kali linux"></category><category term="linux"></category><category term="sysadmin"></category></entry><entry><title>C4android Programming on your Android devices in C/C++</title><link href="https://codeholics.com/c4android-programming-on-your-android-devices-in-cc.html" rel="alternate"></link><published>2015-07-20T05:28:00-04:00</published><updated>2015-07-20T05:28:00-04:00</updated><author><name>root</name></author><id>tag:codeholics.com,2015-07-20:/c4android-programming-on-your-android-devices-in-cc.html</id><summary type="html">&lt;p&gt;I love mobile computing, and I love coding. It is only natural that I would want to do some coding on the go. C4android lets you do just that if you enjoy coding in C/C++ and want to do it easily on your Android device. C4android is a nice …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I love mobile computing, and I love coding. It is only natural that I would want to do some coding on the go. C4android lets you do just that if you enjoy coding in C/C++ and want to do it easily on your Android device. C4android is a nice lightweight IDE that interfaces nicely with the GCC compiler and GDB debugger making it easy to work on any size C/C++ project while on the go. It is also great if your going over an eBook. You can flip back and forth between the book and C4android to test out code examples. This was by far the best \$3 I ever spent on an app and would have spent more if asked to.&lt;/p&gt;
&lt;p&gt;Check out C4android on the Google Play Store:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.n0n3m4.droidc"&gt;
https://play.google.com/store/apps/details?id=com.n0n3m4.droidc
&lt;/a&gt;&lt;/p&gt;</content><category term="Review"></category><category term="android"></category><category term="C"></category><category term="programming"></category><category term="coding"></category><category term="review"></category></entry><entry><title>Make a Bootable Flash Drive from an ISO file in Linux</title><link href="https://codeholics.com/make-a-bootable-flash-drive-from-an-iso-file-in-linux.html" rel="alternate"></link><published>2015-07-17T19:59:00-04:00</published><updated>2015-07-17T19:59:00-04:00</updated><author><name>root</name></author><id>tag:codeholics.com,2015-07-17:/make-a-bootable-flash-drive-from-an-iso-file-in-linux.html</id><summary type="html">&lt;p&gt;Make a Bootable Flash Drive from an ISO file in Linux  &lt;/p&gt;
&lt;p&gt;&lt;em&gt;OS:&lt;/em&gt; &lt;em&gt;nix based systems&lt;br&gt;
&lt;/em&gt;Skill Level:&lt;em&gt; Beginner&lt;br&gt;
&lt;/em&gt;Prerequisites:* Terminal, The Power of Root&lt;/p&gt;
&lt;p&gt;There are a few ways of creating a bootable USB drive. This is my preference. Using dd is quick, easy and available on all *nix systems …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Make a Bootable Flash Drive from an ISO file in Linux  &lt;/p&gt;
&lt;p&gt;&lt;em&gt;OS:&lt;/em&gt; &lt;em&gt;nix based systems&lt;br&gt;
&lt;/em&gt;Skill Level:&lt;em&gt; Beginner&lt;br&gt;
&lt;/em&gt;Prerequisites:* Terminal, The Power of Root&lt;/p&gt;
&lt;p&gt;There are a few ways of creating a bootable USB drive. This is my preference. Using dd is quick, easy and available on all *nix systems. In fact, most GUI tools are just dd wrappers, so lets cut out the fluff and get down to it.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Figure out the device path to your usb drive:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;sudo fdisk -l&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This will list all your drives:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Now using dd use the following command of course replacing the path with the path to the ISO image you want to use on the removable device.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;sudo dd if=/path/to/a.iso of=/dev/sd(x) &amp;amp;&amp;amp; sync&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This might take a few minutes, but once it is done boot from the removable device.&lt;/p&gt;</content><category term="Linux"></category><category term="linux"></category></entry><entry><title>Google Chrome Development Tools for Web Apps</title><link href="https://codeholics.com/google-chrome-development-tools-for-web-apps.html" rel="alternate"></link><published>2015-07-08T15:30:00-04:00</published><updated>2015-07-08T15:30:00-04:00</updated><author><name>root</name></author><id>tag:codeholics.com,2015-07-08:/google-chrome-development-tools-for-web-apps.html</id><summary type="html">&lt;p&gt;Google Chrome Development Tools for Web Apps  &lt;/p&gt;
&lt;p&gt;I have been doing some web app coding recently and thought I would share some of the helpful development tools that are available in Google Chrome. Especially when coding for multiple devices. I will skip over the basic things that have been in …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Google Chrome Development Tools for Web Apps  &lt;/p&gt;
&lt;p&gt;I have been doing some web app coding recently and thought I would share some of the helpful development tools that are available in Google Chrome. Especially when coding for multiple devices. I will skip over the basic things that have been in all browsers for a long time like viewing source and get to the goods.&lt;/p&gt;
&lt;p&gt;Hit Ctrl+Shift+I if your a Hot Key Ninja or got to options in the upper right hand corner and navigate to More Tools -&amp;gt; Development Tools and you should see this appear on the right hand side of your page.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://web-beta.archive.org/web/20150812220856/https://codeholics.com/wp-content/uploads/Selection_518.png"&gt;&lt;br&gt;
&lt;img alt="gChromeDevTools" src="https://web-beta.archive.org/web/20150812220856im_/https://codeholics.com/wp-content/uploads/Selection_518-253x300.png"&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now lets go from my favorite feature on down first view on mobile device just click the phone icon&lt;/p&gt;
&lt;p&gt;&lt;a href="https://web-beta.archive.org/web/20150812220856/https://codeholics.com/wp-content/uploads/Selection_519.png"&gt;&lt;br&gt;
&lt;img alt="gChromeDevToolsMenu" src="https://web-beta.archive.org/web/20150812220856im_/https://codeholics.com/wp-content/uploads/Selection_519.png"&gt;&lt;br&gt;
&lt;/a&gt;&lt;br&gt;
and it will nicely display your web app as it would be viewed on a mobile device&lt;/p&gt;
&lt;p&gt;&lt;a href="https://web-beta.archive.org/web/20150812220856/https://codeholics.com/wp-content/uploads/Selection_520.png"&gt;&lt;br&gt;
&lt;img alt="gChromeDevToolsMobile" src="https://web-beta.archive.org/web/20150812220856im_/https://codeholics.com/wp-content/uploads/Selection_520-228x300.png"&gt;
&lt;/a&gt;&lt;br&gt;
Now lets dive deeper into the mobile options:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://web-beta.archive.org/web/20150812220856/https://codeholics.com/wp-content/uploads/Selection_521.png"&gt;&lt;br&gt;
&lt;img alt="gChromeDevToolsMOpt" src="https://web-beta.archive.org/web/20150812220856im_/https://codeholics.com/wp-content/uploads/Selection_521.png"&gt;&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Device: Select from a long list of Apple and Android devices to test your mobile application on.&lt;/p&gt;
&lt;p&gt;Network: Select different bandwidth simulations to test your app against to see load times&lt;/p&gt;
&lt;p&gt;&lt;a href="https://web-beta.archive.org/web/20150812220856/https://codeholics.com/wp-content/uploads/Selection_522.png"&gt;&lt;br&gt;
&lt;img alt="Rotate" src="https://web-beta.archive.org/web/20150812220856im_/https://codeholics.com/wp-content/uploads/Selection_522.png"&gt; 
&lt;/a&gt;&lt;br&gt;
Clicking this will rotate the screen 180 degrees.&lt;/p&gt;
&lt;p&gt;Now lets say some items or not lining up correctly and its time to trouble shoot it. The development tools allows you to inspect elements of the page and edit attributes so you can see what effects changes will have on your application user interface in real time.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://web-beta.archive.org/web/20150812220856/https://codeholics.com/wp-content/uploads/Selection_524.png"&gt;&lt;br&gt;
&lt;img alt="gChromeDevToolsLiveEdit" src="https://web-beta.archive.org/web/20150812220856im_/https://codeholics.com/wp-content/uploads/Selection_524-1024x338.png"&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;These development tools should be helpful to anyone developing web apps for todays multi-device world.&lt;/p&gt;</content><category term="Coding"></category><category term="coding"></category><category term="frontend"></category><category term="dev tools"></category></entry><entry><title>Microsoft Visual Studio and SQL Management Studio error Exception has been thrown by the target of an invocation</title><link href="https://codeholics.com/microsoft-visual-studio-and-sql-management-studio-error-exception-has-been-thrown-by-the-target-of-an-invocation.html" rel="alternate"></link><published>2015-06-18T14:56:00-04:00</published><updated>2015-06-18T14:56:00-04:00</updated><author><name>root</name></author><id>tag:codeholics.com,2015-06-18:/microsoft-visual-studio-and-sql-management-studio-error-exception-has-been-thrown-by-the-target-of-an-invocation.html</id><summary type="html">&lt;p&gt;I recently ran into an error one day trying to open my SQL Management Studio application. I have been using this application for years now but one day it just would not launch and just displayed an error message Exception has been thrown by the target of an invocation.&lt;/p&gt;
&lt;p&gt;I …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I recently ran into an error one day trying to open my SQL Management Studio application. I have been using this application for years now but one day it just would not launch and just displayed an error message Exception has been thrown by the target of an invocation.&lt;/p&gt;
&lt;p&gt;I found this error is more common with Visual Studio but I can see how this might also affect more than just Microsoft applications.&lt;/p&gt;
&lt;p&gt;In order to fix this you will have to manually edit your registry. This error is caused because the PATH value is more than 2078 characters long. You can remove the lines for applications you no longer use or shorten the path to resolve this issue.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;br&gt;
This is how to fix it:&lt;br&gt;
&lt;/strong&gt;&lt;/p&gt;</content><category term="Windows"></category><category term="microsoft"></category><category term="windows"></category><category term="mssql"></category></entry><entry><title>More Docker: Dockerfile to build a MongoDB Image</title><link href="https://codeholics.com/more-docker-dockerfile-to-build-a-mongodb-image.html" rel="alternate"></link><published>2015-02-26T03:43:00-05:00</published><updated>2015-02-26T03:43:00-05:00</updated><author><name>root</name></author><id>tag:codeholics.com,2015-02-26:/more-docker-dockerfile-to-build-a-mongodb-image.html</id><summary type="html">&lt;p&gt;Last post (&lt;a href="http://codeholics.com/2015/02/getting-started-with-docker/" title="Getting Started With Docker"&gt;Getting Started With Docker&lt;/a&gt;) I ended off with saying I would come back and show how to set up a mongodb docker image. If you go to https://registry.hub.docker.com/ on the first page you can find the official mongodb docker image. This is not that …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Last post (&lt;a href="http://codeholics.com/2015/02/getting-started-with-docker/" title="Getting Started With Docker"&gt;Getting Started With Docker&lt;/a&gt;) I ended off with saying I would come back and show how to set up a mongodb docker image. If you go to https://registry.hub.docker.com/ on the first page you can find the official mongodb docker image. This is not that point of this post though. This is about getting to know and understand Docker, so we are going to do it from a base image and create a Dockerfile to do all the work for use. I like CentOS so that is what I am going to use but you can go ahead and pick your poison.&lt;/p&gt;
&lt;p&gt;A Dockerfile is a image build script. Before creating one of these it is good to think about what steps you would take to build an image manually.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Mongodb repo&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install the packages
&lt;code&gt;yum -y install mongodb-org-server.x86_64 mongodb-org-shell.x86_64 mongodb-org-tools.x86_64&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Easy enough lets build the file:&lt;/p&gt;
&lt;p&gt;Using your favorite text editor crate Dockerfile:&lt;/p&gt;
&lt;p&gt;Lets break it down a bit:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;COPY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Copy a file into the image.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;RUN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Run a command&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;EXPOSE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Expose a network port&lt;/p&gt;
&lt;p&gt;Now that we have our DockerFile run:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;so&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker build -t mongodb.centos .
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It will build the image and now you have your very own Mongodb Docker image.&lt;/p&gt;
&lt;p&gt;Now to run it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker run -d -p 27017:27017 mongodb.centos /usr/bin/mongod --port 27017  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;-d&lt;/em&gt; Run as a daemon&lt;/p&gt;
&lt;p&gt;&lt;em&gt;-p 27017:27017&lt;/em&gt; Expose port 27017 on local port 27017&lt;/p&gt;
&lt;p&gt;&lt;em&gt;/usr/bin/mongod port 27017&lt;/em&gt; Start the mongodb server and run it on port 27017&lt;/p&gt;
&lt;p&gt;Now I hope you see the power already. I could run 100 of these just by setting up a bash script with a loop.&lt;/p&gt;
&lt;p&gt;Now to connect to this server from the local machine run the &lt;code&gt;mongo&lt;/code&gt; command and there you have it.&lt;/p&gt;
&lt;p&gt;Hopefully this has displayed Docker in a way that makes you as excited about it as it did me when I really started digging in. If you want to collaborate with a friend or coworker on a project you could send him over your Dockerfile and know that both of you have the same environment. If you have a ready image you can just push it over to them the way you would with git. Even better you can easily push to Dev, QA, Stage and Prod without long build times and outage windows. If your not excited you should check your pulse! This does not mean docker is 100% production ready, but I am sure it will be shortly with all the attention it is getting.&lt;/p&gt;</content><category term="misc"></category><category term="sysadmin"></category><category term="docker"></category><category term="mongodb"></category><category term="linux"></category></entry><entry><title>VMware not enough physical memory windows 8.1</title><link href="https://codeholics.com/vmware-not-enough-physical-memory-windows-8-1.html" rel="alternate"></link><published>2015-02-05T16:06:00-05:00</published><updated>2015-02-05T16:06:00-05:00</updated><author><name>root</name></author><id>tag:codeholics.com,2015-02-05:/vmware-not-enough-physical-memory-windows-8-1.html</id><summary type="html">&lt;p&gt;I have been using VMware for a long time now and this is the first I have ever seen an error with physical memory when trying to run my VMs. My VMs were running fine until my Windows 8.1 rebooted after automatic updates. After the reboot my VM wouldnt …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I have been using VMware for a long time now and this is the first I have ever seen an error with physical memory when trying to run my VMs. My VMs were running fine until my Windows 8.1 rebooted after automatic updates. After the reboot my VM wouldnt start and would displayed a messages as if my system had 4gb of ram but I was trying to allocate 8gb of ram.&lt;/p&gt;
&lt;p&gt;During my troubleshooting I did exactly what the message said by lowering the memory I have assigned to that machine to 1gb. Rebooted my VM and another message came up but this time it said to allocate less than 600kb!&lt;/p&gt;
&lt;p&gt;Long story short, there was no issue with the my system memory but Windows update&lt;br&gt;
&lt;em&gt;KB2995388&lt;/em&gt;&lt;br&gt;
broke my VMware Workstation 10.&lt;/p&gt;
&lt;p&gt;++This is how you fix this.++&lt;/p&gt;</content><category term="Windows"></category><category term="os"></category><category term="windows"></category><category term="vmware"></category></entry><entry><title>ClamAV (ClamTK) Anti-Virus For Ubuntu</title><link href="https://codeholics.com/clamav-clamtk-anti-virus-for-ubuntu.html" rel="alternate"></link><published>2015-01-26T07:09:00-05:00</published><updated>2015-01-26T07:09:00-05:00</updated><author><name>root</name></author><id>tag:codeholics.com,2015-01-26:/clamav-clamtk-anti-virus-for-ubuntu.html</id><summary type="html">&lt;p&gt;I reviewed and tested every Ubuntu anti-virus I was able to get my hands on, ClamTK is by far the best.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Simple Instructions on what is needed to install a fully updated anti-virus for Ubuntu.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;* Viruss are not common in Linux, however, this is not a bad idea if you …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I reviewed and tested every Ubuntu anti-virus I was able to get my hands on, ClamTK is by far the best.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Simple Instructions on what is needed to install a fully updated anti-virus for Ubuntu.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;* Viruss are not common in Linux, however, this is not a bad idea if you have users submitting data to your server. *&lt;/p&gt;
&lt;p&gt;&lt;em&gt;You can watch a video on how to install this&lt;/em&gt;&lt;br&gt;
&lt;a href="https://web-beta.archive.org/web/20150404153404/https://www.youtube.com/watch?v=REqitWT1Wu0"&gt;https://www.youtube.com/watch?v=REqitWT1Wu0&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;ClamTKs application icon&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://web-beta.archive.org/web/20150404153404/http://codeholics.com/wp-content/uploads/ClamTK_logo.png"&gt;&lt;img alt="ClamTK_logo" src="https://web-beta.archive.org/web/20150404153404im_/http://codeholics.com/wp-content/uploads/ClamTK_logo.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;ClamTKs newest GUI&lt;/em&gt;  &lt;/p&gt;
&lt;p&gt;Your application GUI might appear different if you didnt grab the update form the website.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://web-beta.archive.org/web/20150404153404/http://codeholics.com/wp-content/uploads/ClamTK.png"&gt;&lt;img alt="ClamTK" src="https://web-beta.archive.org/web/20150404153404im_/http://codeholics.com/wp-content/uploads/ClamTK.png"&gt;&lt;/a&gt;&lt;/p&gt;</content><category term="Linux"></category><category term="os"></category><category term="linux"></category><category term="review"></category><category term="software"></category></entry><entry><title>Linux Backup Restore with tar (part 1 of 2)</title><link href="https://codeholics.com/linux-backup-restore-with-tar-part-1-of-2.html" rel="alternate"></link><published>2015-01-04T02:40:00-05:00</published><updated>2015-01-04T02:40:00-05:00</updated><author><name>root</name></author><id>tag:codeholics.com,2015-01-04:/linux-backup-restore-with-tar-part-1-of-2.html</id><summary type="html">&lt;p&gt;&lt;em&gt;OS:&lt;/em&gt; Linux&lt;br&gt;
&lt;em&gt;Skill Level:&lt;/em&gt; Intermediate&lt;br&gt;
&lt;em&gt;Prerequisites:&lt;/em&gt; Linux CLI and Bash Scripting&lt;br&gt;
&lt;em&gt;Language:&lt;/em&gt; Bash Shell Scripting&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Intro:&lt;/em&gt;&lt;br&gt;
There are a lot of great open source and commercial backup solutions and what you will find if you look under the hood of these software packages is that most of them are just …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;em&gt;OS:&lt;/em&gt; Linux&lt;br&gt;
&lt;em&gt;Skill Level:&lt;/em&gt; Intermediate&lt;br&gt;
&lt;em&gt;Prerequisites:&lt;/em&gt; Linux CLI and Bash Scripting&lt;br&gt;
&lt;em&gt;Language:&lt;/em&gt; Bash Shell Scripting&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Intro:&lt;/em&gt;&lt;br&gt;
There are a lot of great open source and commercial backup solutions and what you will find if you look under the hood of these software packages is that most of them are just interfacing or wrapping over tar. For my home needs I decided it would be simple and fun to just write my own basic backup software using tar and a script.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Software Requirements:&lt;/em&gt;&lt;br&gt;
1. Backup: Script must backup all important files on my system and exclude files that are not needed. The backup tar.gz file must contain the name of the host the it backed up and the date of the backup.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;hostname-backup-0000-00-00.tar.gz&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Retire old backups: Script must be able to remove old backups after a specified time period.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This are simple backup requirements for my own home use, and they might not apply to everyones individual needs.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Part 1:&lt;/em&gt;&lt;br&gt;
First things we need to backup the data we want and exclude what we do not need. Lets break down the tar arguments we will need to get this accomplished.&lt;/p&gt;
&lt;p&gt;Backup archive to tar.gz file:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;tar cpzf [tar.bz file] -X [exclude list] [directory]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;czf&lt;/code&gt; create file.tar.bz  &lt;/p&gt;
&lt;p&gt;&lt;code&gt;p&lt;/code&gt; preserve file permissions.  &lt;/p&gt;
&lt;p&gt;&lt;code&gt;X&lt;/code&gt; exclude files listed in this file  &lt;/p&gt;
&lt;p&gt;These tar arguments should cover all we need for our basic backup script. Time to start building the script.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;vim backup.sh (call it whatever you want)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For the sake of simplicity and organization I am going to break this down into two functions. The first will be  the backup function. We will also need a few global variables (I might change these to local vars depending on the needs of the script as I move forward).&lt;/p&gt;
&lt;p&gt;having our global variables up top makes it very easy to edit our settings if needed later on. The one we need to look at is our exclude_list. I put this list in the same directory as the backup script. Here is what mine looks like:&lt;/p&gt;
&lt;p&gt;Now set this as a cron job to run at your desired backup intervals. I have mine set to run once a week as my data does not change all that often and the world would not stop spinning if I lost something between that week. Create a cron file call backup in &lt;code&gt;/etc/cron.d/&lt;/code&gt; with the following (adjust to meet your needs).&lt;/p&gt;
&lt;p&gt;This sets the script to run at 12am every Saturday.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Part 2:&lt;/em&gt;  &lt;/p&gt;
&lt;p&gt;This part gets a little more tricky. We will need to write a function to look at the backup tar file and check if it is beyond a date we specify to retire that backup. Since I am going to have it set to retire older backups before it takes the new backup I will test the files creation date against the current date and see if it is beyond our retention policy. I am going to call this function retire.&lt;/p&gt;
&lt;p&gt;First lets get the last modified time.  We can do this with the stat command:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;stat -c%y [tar archive] | cut -c1-10&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-c&lt;/code&gt; or &lt;code&gt;format=&lt;/code&gt;: this lets us modify the output of the stat command&lt;/p&gt;
&lt;p&gt;&lt;code&gt;%y&lt;/code&gt; gives us the date the file was last modified&lt;/p&gt;
&lt;p&gt;Output of stat command:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;2014-11-22 05:41:56.045547078 -0800&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;At this point in time we only care about the date so we can pipe this to cut command to snip off what we need.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cut -c1-10&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-c&lt;/code&gt; characters to cut&lt;/p&gt;
&lt;p&gt;This give us just what we need:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;2014-11-22&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;for this I am also going to need one more global var called &lt;code&gt;retire_after&lt;/code&gt;. This will be our retention policy set in how many days we would like to keep the backups. I am going to set mine for 14 days (two weeks). The easiest way to explain this function will be to show it first and go over what it is doing after.&lt;/p&gt;
&lt;p&gt;First we get a list of all the files in the backup location, then we get the retire date. Once we have those things we check to see if the list is empty.&lt;br&gt;
&lt;code&gt;$valid&lt;/code&gt;&lt;br&gt;
hold a regex expression that we use to check if&lt;br&gt;
&lt;code&gt;$files[0]&lt;/code&gt;&lt;br&gt;
contains a &lt;code&gt;\*&lt;/code&gt; at the end of its string. If it does contain a &lt;code&gt;\*&lt;/code&gt; it means the folder was empty.  Now loop through the backup files and figure out if they match the retire date. If they do then we remove them. Then we add the retire function under the main section of our script:&lt;/p&gt;
&lt;p&gt;This completes our requirements for a backup script. Here is the script in it entirety.&lt;/p&gt;
&lt;p&gt;If you have been following along you probably noticed a few issues with the script.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Known Issues:&lt;/em&gt;  &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Since the script is set to run weekly we can only retire on weekly increments. While this works just fine for me it might not work for every situation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If the script gets skipped one week it might strand a older backup. This can be cured with more tests on the tar files for age in the retire function.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;em&gt;Conclusion:&lt;/em&gt;  &lt;/p&gt;
&lt;p&gt;I am sure there are other issue with this script but for my basic needs at home this does the trick. I will post the full script to the Codeholics github page. Part two of this post will be writing the wrapper script for restoring files.&lt;/p&gt;</content><category term="Linux"></category><category term="linux"></category><category term="shell"></category><category term="coding"></category></entry><entry><title>File count from the command line on a Linux system</title><link href="https://codeholics.com/file-count-from-the-command-line-on-a-linux-system.html" rel="alternate"></link><published>2014-10-21T05:34:00-04:00</published><updated>2014-10-21T05:34:00-04:00</updated><author><name>root</name></author><id>tag:codeholics.com,2014-10-21:/file-count-from-the-command-line-on-a-linux-system.html</id><summary type="html">&lt;p&gt;&lt;em&gt;OS:&lt;/em&gt; Linux  &lt;br&gt;
&lt;em&gt;Skill Level:&lt;/em&gt; Beginner&lt;br&gt;
&lt;em&gt;Prerequisites:&lt;/em&gt; Basic Linux CLI and regular expression understanding&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Intro:&lt;/em&gt;  &lt;/p&gt;
&lt;p&gt;When a folder only has a few items in it this trick is not that important, but let say the folder you are looking at has 754,586 files in it? Here is a quick trick …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;em&gt;OS:&lt;/em&gt; Linux  &lt;br&gt;
&lt;em&gt;Skill Level:&lt;/em&gt; Beginner&lt;br&gt;
&lt;em&gt;Prerequisites:&lt;/em&gt; Basic Linux CLI and regular expression understanding&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Intro:&lt;/em&gt;  &lt;/p&gt;
&lt;p&gt;When a folder only has a few items in it this trick is not that important, but let say the folder you are looking at has 754,586 files in it? Here is a quick trick to get an accurate count of the items in a folder.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Example Folder Listing:&lt;/em&gt;  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rwxr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;xr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vesc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vesc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1465&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Apr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2014&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="n"&gt;drwxrwxr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vesc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vesc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;May&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Code&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="n"&gt;drwxrwxr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vesc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vesc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Apr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2014&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Downloads&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rwxrwxr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vesc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vesc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1279&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Aug&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;07&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ipcheck&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vesc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vesc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Oct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dat&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vesc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vesc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6045&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Aug&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;08&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;movielist&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;txt&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;294944&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Apr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rwxr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;xr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vesc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vesc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;529276&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Apr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2014&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;slowhttptest&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="n"&gt;drwxrwxr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vesc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vesc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Jan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2014&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;somefile&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Total items in folder:&lt;/em&gt;  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;ls&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;wc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vesc@indigofs ~\&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ls&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;wc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="mi"&gt;9&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Number of files in the folder:&lt;/em&gt;  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;ls&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;grep&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;^-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;wc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vesc@indigofs ~\&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ls&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;grep&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;^-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;wc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Number of sub-folders in the folder:&lt;/em&gt;  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;ls&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;grep&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;wc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vesc\@indigofs ~\&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ls&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;grep&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;wc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Linux"></category><category term="os"></category><category term="linux"></category><category term="shell"></category><category term="cli"></category><category term="sysadmin"></category></entry><entry><title>Managing BTRFS Snapshots</title><link href="https://codeholics.com/managing-btrfs-snapshots.html" rel="alternate"></link><published>2014-10-14T23:12:00-04:00</published><updated>2014-10-14T23:12:00-04:00</updated><author><name>root</name></author><id>tag:codeholics.com,2014-10-14:/managing-btrfs-snapshots.html</id><summary type="html">&lt;p&gt;&lt;em&gt;Skill:&lt;/em&gt; Advanced&lt;br&gt;
&lt;em&gt;OS:&lt;/em&gt; Linux (OpenSUSE 13.1)&lt;br&gt;
&lt;em&gt;Prerequisites:&lt;/em&gt; A drive with btrfs  &lt;/p&gt;
&lt;p&gt;&lt;em&gt;Intro:&lt;/em&gt;&lt;br&gt;
When I first installed OpenSUSE 13.1 it gave me the option of using btrfs for my file system. It warned me it was experimental but after reading up about the benefits I decided to live on …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;em&gt;Skill:&lt;/em&gt; Advanced&lt;br&gt;
&lt;em&gt;OS:&lt;/em&gt; Linux (OpenSUSE 13.1)&lt;br&gt;
&lt;em&gt;Prerequisites:&lt;/em&gt; A drive with btrfs  &lt;/p&gt;
&lt;p&gt;&lt;em&gt;Intro:&lt;/em&gt;&lt;br&gt;
When I first installed OpenSUSE 13.1 it gave me the option of using btrfs for my file system. It warned me it was experimental but after reading up about the benefits I decided to live on the wild side and use it on my laptop. The drive is a fairly small 120gb SSD so giving up the chunk to btrfs was a bit of a sacrifice. I figured if push came to crash it would add some value and it is a new file system to play with. One day I was running my updates and the install crapped out in the middle saying I had no space available and at this point my X locked up and crapped out. I did a Ctrl+Alt+F1 to get to a command line and figure out just what the hell is happening. I do a df -h and can see no issues with my space. After a while I figure out it was my btrfs snapshots that were eating up all my space. Here is what I did to correct this issue, and set the configuration file to keep from having this issue in the future.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Snapper:&lt;/em&gt;&lt;br&gt;
Snapper is the snapshot manager tool for btrfs. Doing a snapper help should give you all the information you need to know about the basic usage and to get your system back up and running if your running btrfs and notice programs are complaining about space when you can not see why.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;snapper list  &lt;br&gt;
List all snapshots&lt;br&gt;
Do this as root and you should see something similar to this:  &lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Type    |  #      |  Pre #  | Date                               | User  | Cleanup  | Description    | Userdata    
-++-+++-++
single   | 0       |           |                                          | root  |                | current          |  
single   | 1990 |           | Sun Oct 5 00:45:02 2014 | root | timeline   | timeline         |   
single   | 2011 |           | Mon Oct 6 07:00:01 2014 | root | timeline  | timeline         |     
pre       | 2015 |            | Mon Oct 6 10:10:41 2014 | root | number  | zypp(zypper)  |    
post     | 2016 | 2015   | Mon Oct 6 10:10:45 2014 | root | number  |                         
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Things to notice:  &lt;/p&gt;
&lt;p&gt;Type Single: A single timeline snapshot taken as part of btrfs operation  &lt;/p&gt;
&lt;p&gt;pre/post: These are snapshots taken before and after a zypper update  &lt;/p&gt;
&lt;p&gt;# This is the number to reference a snapshot  &lt;/p&gt;
&lt;p&gt;Date Date the snapshot was taken by default btrfs keeps a lot of snapshots. I will show you how to adjust this at the end.&lt;/p&gt;
&lt;p&gt;2. Delete some old snapshot to free up some space  &lt;/p&gt;
&lt;p&gt;&lt;code&gt;snapper delete&lt;/code&gt;  &lt;/p&gt;
&lt;p&gt;&lt;code&gt;snapper delete 1990 #this will delete single&lt;/code&gt;    &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Roll Back: If this happened to you like it did to me while in the middle of a update you will need this step  &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;snapper&lt;/code&gt;  &lt;/p&gt;
&lt;p&gt;&lt;code&gt;snapper -v undochange [newer]..[older]&lt;/code&gt;  &lt;/p&gt;
&lt;p&gt;&lt;code&gt;snapper -v undochange 2041..2040 #This will undo the update changes made by zypper&lt;/code&gt;  &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Configure snapper retention:  &lt;/li&gt;
&lt;li&gt;&lt;code&gt;vim /etc/snapper/configs/root&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Find and edit this section of the file to meet your needs and space limitations:  &lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;limits&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;timeline&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;cleanup&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="nv"&gt;TIMELINE_MIN_AGE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1800&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;
&lt;span class="nv"&gt;TIMELINE_LIMIT_HOURLY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="nv"&gt;TIMELINE_LIMIT_DAILY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="nv"&gt;TIMMELINE_LIMIT_MONTHLY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="nv"&gt;TIMELINE_LIMIT_YEARLY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;By default it keeps the 10 last snapshots of each hourly, daily, monthly and yearly.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Conclusion:&lt;/em&gt;  &lt;/p&gt;
&lt;p&gt;I hear they have worked on fixing this issue in the newer releases, but if you find yourself in my predicament I hope this helps. The thing I found ironic was the snapshot is what did me in and is what saved me after the fact.&lt;/p&gt;</content><category term="Linux"></category></entry><entry><title>SSH Login Banner</title><link href="https://codeholics.com/ssh-login-banner.html" rel="alternate"></link><published>2014-10-14T01:27:00-04:00</published><updated>2014-10-14T01:27:00-04:00</updated><author><name>root</name></author><id>tag:codeholics.com,2014-10-14:/ssh-login-banner.html</id><summary type="html">&lt;p&gt;Want a custom banner or warning message when a user connects via SSH on your server?  &lt;/p&gt;
&lt;p&gt;&lt;em&gt;Skill level:&lt;/em&gt; Beginner&lt;br&gt;
&lt;em&gt;OS:&lt;/em&gt; Linux&lt;br&gt;
&lt;em&gt;Prerequisites:&lt;/em&gt; Understand how to edit a file with vim or other text editor in Linux.&lt;br&gt;
&lt;em&gt;Dependencies:&lt;/em&gt;
&lt;em&gt;Config files:&lt;/em&gt;&lt;br&gt;
&lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;
&lt;code&gt;/etc/issue.net&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; and …&lt;/li&gt;&lt;/ol&gt;</summary><content type="html">&lt;p&gt;Want a custom banner or warning message when a user connects via SSH on your server?  &lt;/p&gt;
&lt;p&gt;&lt;em&gt;Skill level:&lt;/em&gt; Beginner&lt;br&gt;
&lt;em&gt;OS:&lt;/em&gt; Linux&lt;br&gt;
&lt;em&gt;Prerequisites:&lt;/em&gt; Understand how to edit a file with vim or other text editor in Linux.&lt;br&gt;
&lt;em&gt;Dependencies:&lt;/em&gt;
&lt;em&gt;Config files:&lt;/em&gt;&lt;br&gt;
&lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;
&lt;code&gt;/etc/issue.net&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; and look for the line with &lt;code&gt;Banner&lt;/code&gt; in it and point it to your &lt;code&gt;/etc/issue.net&lt;/code&gt; file:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Banner /etc/issue.net  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Generate a banner:&lt;br&gt;
&lt;code&gt;figlet -f banner [string]&lt;/code&gt;  &lt;/li&gt;
&lt;li&gt;Copy and paste your banner into &lt;code&gt;/etc/issue.net&lt;/code&gt; to add your message.  &lt;/li&gt;
&lt;li&gt;Restart sshd:&lt;br&gt;
&lt;code&gt;sudo -i service sshd restart&lt;/code&gt;  &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now connect to your box:&lt;br&gt;
&lt;a href="https://web-beta.archive.org/web/20150725063050/http://codeholics.com/wp-content/uploads/2014/10/Selection_221.png"&gt;&lt;img alt="ssh-login" src="https://web-beta.archive.org/web/20150725063050im_/http://codeholics.com/wp-content/uploads/2014/10/Selection_221-300x72.png"&gt;&lt;/a&gt;&lt;/p&gt;</content><category term="Linux"></category><category term="sysadmin"></category><category term="os"></category><category term="linux"></category></entry></feed>