Cody Bunch Some Random IT Guy - OpenStack, DevOps, Cloud, Things

The 8-Minute AeroPress

Today we take a little bit of a detour into coffee land to talk about my preferred method for making coffee. Specifically, how I make an 8-Minute AeroPress.

Why 8 minutes? The trick here, is that we use the timing to get our water to within an ideal temperature range for steeping and brewing with the AeroPress. AeroPress recommends, and I have found, that along with a longer steeping time, the lower temperature produces an amazing cup of coffee.

Gear

Of course there is some gear, and disclaimer of disclaimer, these are all smile.amazon links.

Note: You don’t need these specific things. They’re the ones I’ve found to work best for me.

You’ll notice I left the actual coffee off that list. This is because that is super highly subjective. My current goto is Cottonwood from Brown Coffee Co.. Great coffee, great consistency, and roasted in a way I aspire to get to in my own roasting.

Setup

First things first, we need to get the grind right. For the Porlex Mini linked above, this is 7 “clicks”. Clicks? Yes, clicks:

Porlex Mini

On the top half of the grinder, turn the knob 6 “clicks” counterclockwise.

For other grinders you are looking for a grind a bit finer than what you’d use for French Press. This is because we’re going to be steeping for a bit longer than is typical, and want to get the extraction just so.

Process

  1. Fill the kettle, set it to boil
  2. Set the funnel into your mug
  3. Grind 1.25 “scoops” or about 16.5 or 17g of coffee
  4. Set up for an “Inverted AeroPress”:

Inverted AeroPress

Image CC licensed

  1. Dump the grounds into the AeroPress.

At about this point, the kettle should be boiling and click itself off. Here is where the first 4 minutes of the 8 comes from. Set a timer for 4 minutes to let the water cool.

  1. Add water to the first marker (should be number 3 if inverted). About 50g
  2. Using the back of the scoop, stir gently
  3. Place the filter in the cover, place the cover filter side up, over the end of the AeroPress, and wet the filter (just wet it, we add the rest of the water later).
  4. Wait another 4 minutes (you see, 8 minutes)
  5. Add the rest of the water. I shoot to fill to about 1cm from the edge, or about 250g total in water.
  6. Screw filter on
  7. Flip into funnel and press

OSX Update All The Things

I have a little alias, yes I do. I have a little alias, how about you?

Specifically, this alias keeps my box up to date, and is derived from @mathis’s excellent dotfiles: https://github.com/mathiasbynens/dotfiles/blob/master/.aliases#L56-L57

alias update='sudo softwareupdate -i -a; \
    brew update; \
    brew upgrade; \
    brew cleanup; \
    brew cask outdated | xargs brew cask reinstall; \
    npm install npm -g; \
    npm update -g; \
    sudo gem update --system; \
    sudo gem update; \
    sudo gem cleanup; \
    vagrant plugin update; \
    sudo purge'

Hope that helps someone other than me.

Upgrading UniFi Controller on UBNT Cloud Key by Hand

Today I needed to update the version of the UniFi Controller that runs on my UBNT Cloud Key. To do this, I basically followed the directions here.

Upgrading UniFi Controller on UBNT Cloud Key

To do the upgrade:

  • Log directly into the CloudKey over ssh
  • wget the new firmware
  • dpkg -i new_firmware.deb
  • Hop over to the web portal for any additional steps

Here is what that looks like from the cli:



 ___ ___      .__________.__
|   |   |____ |__\_  ____/__|
|   |   /    \|  ||  __) |  |   (c) 2013-2016
|   |  |   |  \  ||  \   |  |   Ubiquiti Networks, Inc.
|______|___|  /__||__/   |__|
           |_/                  http://www.ubnt.com

     Welcome to UniFi CloudKey!

root@UniFi-CloudKey:~# cd /tmp
root@UniFi-CloudKey:/tmp# wget http://dl.ubnt.com/unifi/4.8.12/unifi_sysvinit_all.deb
--2017-06-12 20:37:51--  http://dl.ubnt.com/unifi/4.8.12/unifi_sysvinit_all.deb
Resolving www.ubnt.com (www.ubnt.com)... 52.24.172.6, 35.162.195.66, 54.69.255.156
Connecting to www.ubnt.com (www.ubnt.com)|52.24.172.6|:443... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: http://dl.ubnt.com/unifi/4.8.12/unifi_sysvinit_all.deb [following]
converted 'http://dl.ubnt.com/unifi/4.8.12/unifi_sysvinit_all.deb' (ANSI_X3.4-1968) -> 'http://dl.ubnt.com/unifi/4.8.12/unifi_sysvinit_all.deb' (UTF-8)
--2017-06-12 20:37:52--  http://dl.ubnt.com/unifi/4.8.12/unifi_sysvinit_all.deb
Resolving dl.ubnt.com (dl.ubnt.com)... 54.230.81.210
Connecting to dl.ubnt.com (dl.ubnt.com)|54.230.81.210|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 145135070 (138M) [application/x-debian-package]
Saving to: 'unifi_sysvinit_all.deb'

unifi_sysvinit_all.deb 100%[===========================>] 138.41M   932KB/s   in 2m 47s

2017-06-12 20:40:39 (851 KB/s) - 'unifi_sysvinit_all.deb' saved [145135070/145135070]

root@UniFi-CloudKey:/tmp# dpkg -i unifi_sysvinit_all.deb
(Reading database ... 15695 files and directories currently installed.)
Preparing to unpack unifi_sysvinit_all.deb ...
Unpacking unifi ...
Setting up unifi ...
Processing triggers for systemd ...

Once that wraps up, you can head over to your web portal. If it’s anything like mine, you’ll see a DB migration in process:

Database Migration

After that is done, you can log in.

Wrapping up the upgrade

If you have other UBNT gear on your network, it too may need an upgrade. For this I tend to work from the outside in. In this case that means first upgrading the AP’s, then the switch:

Rolling AP Upgrade

Rolling updates can be found under the APS tab of the UniFi interface:

Find the rolling updates

With that complete, upgrade the rest as needed.

Updated Vagrant Boxes for OpenStack Cookbook 3rd Edition

A reader reached out a day or so ago to point out that the Vagrant images used in the 3rd edition of the OpenStack Cookbook had gone missing.

Why? Well, long story short, I accidentally the images.

That said, I buit new ones, which live on Atlas here.

Changes in this release:

  • Updated to ubuntu 14.04.5
  • Updated NIC drivers
    • Virtualbox: Virtio
    • VMware: vmxnet3
  • Changed from preseed to kickstart

The images are still rather large. However, as we are in the process of writing the 4th edition, I’ll likely leave them that size.

Fixing Sublime (subl) CLI in tmux

This fix is borrowed from here, with some minor adjustments.

brew install reattach-to-user-namespace
echo "set-option -g default-command "reattach-to-user-namespace -l ${SHELL}" \
    | tee -a ~/.byobu/.tmux.conf
byoby kill-server

Then restart your sessions as normal.

Why Windows Update? (re)Build it on the fly.

This sound familiar? You use a *nix based OS as a daily driver. Be that OSX or some flavor of Linux. You’ve got say, 95% of what you need to do covered, but every now and again (like pulling up an old Java app, or running a specific version of IE), you keep a Windows VM around.

Ok you think, this not so bad. Until you find, it’s been forever since you last opened said Windows VM, and now you need updates and such, and then the app updates, and suddenly you have spent more time caring and feeding Windows than doing work.

At least, I find myself here too often. I hated it. So like any good lazy-admin. I fixed it. I no longer keep a Windows VM around all the time. Instead I build it fresh, each and every time I need it, pulling in all the relevant security patches, tools, and so forth. What follows then, is the actual ‘how’, behind it.

But first, the short version, because this will be a huge post:

brew update
brew cask install packer
brew cask install vagrant
brew cask install vmware-fusion
vagrant plugin install vagrant-vmware-fusion
vagrant plugin license vagrant-vmware-fusion ~/Downloads/license.lic
git clone https://github.com/boxcutter/windows ~/projects/templates
cd ~/projects/templates
make vmware/eval-win7x64-enterprise-ssh.json
vagrant box add \
    -name Win10x64 \
    ./box/vmware/eval-win10x64-enterprise-ssh-nocm-1.0.4.box

Before You Start

Before you head down this road, you will need a few tools:

  • Packer
  • Vagrant
  • Virtualbox or VMware Fusion/Workstation (examples here are Fusion, but should work either way)
  • The ISO files. That is, if you are doing non-eval versions

Getting Started

We’ll work with the assumption that you have your tools installed and, if needed licensed. The tl;dr of that process for OSX is:

brew update
brew cask install packer
brew cask install vagrant
brew cask install vmware-fusion
brew cask install virtualbox
vagrant plugin install vagrant-vmware-fusion
vagrant plugin license vagrant-vmware-fusion ~/Downloads/license.lic

Once you have the tools, at a high level, the process is:

  • Download (or write) packer definitions
  • Download (or write) post-install scripts
  • Run the things

The Packer Environment

The good folks behind boxcutter have produced quite a robust set of packer environment files which provide an excellent foundation from which to start. They cover most recent windows versions from win7 => current desktop wise and 2008R2 => current server wise. I would advise forking that repo to provide a good jumping off point.

Now, let’s customize one for Windows 10:

git clone https://github.com/boxcutter/windows ~/projects/templates
cd ~/projects/templates

In here you will want to edit either win10x64-enterprise-ssh.json or eval-win10x64-enterprise-ssh.json respectively.

Note: The difference here is between licensed install media or not. Our example follows the eval version.

Note 2: I’m using ssh over winrm here because that works well for me on OSX. The winrm versions of these files are similar enough, however.

You are looking for this section of the file:

"provisioners": [
  {
    "environment_vars": [
      "CM=",
      "CM_VERSION=",
      "UPDATE="
    ],
    "execute_command": " cmd /c C:/Windows/Temp/script.bat",
    "remote_path": "/tmp/script.bat",
    "scripts": [
      "script/vagrant.bat",
      "script/cmtool.bat",
      "script/vmtool.bat",
      "script/clean.bat",
      "script/ultradefrag.bat",
      "script/sdelete.bat"
    ],
    "type": "shell"
  },
  {
    "inline": [
      "rm -f /tmp/script.bat"
    ],
    "type": "shell"
  }
],

In that section, between the bat files and the inline script, we inject our custom powershell:

"provisioners": [
  {
    "type": "file",
    "source": "script/custom.ps1",
    "destination": "C:/Windows/Temp/custom.ps1"
  },
  {
    "environment_vars": [
      "CM=",
      "CM_VERSION=",
      "UPDATE="
    ],
    "execute_command": " cmd /c C:/Windows/Temp/script.bat",
    "remote_path": "/tmp/script.bat",
    "scripts": [
      "script/vagrant.bat",
      "script/cmtool.bat",
      "script/vmtool.bat",
      'script/custom_launcher.bat',
      "script/clean.bat",
      "script/ultradefrag.bat",
      "script/sdelete.bat"
    ],
    "type": "shell"
  },
  {
    "inline": [
      "rm -f /tmp/script.bat"
    ],
    "type": "shell"
  }
],

The Install Script

As you saw in the prior section, we added three things:

  • A file provisioner to copy in our PowerShell script
  • The script script/custom_launcher.bat
  • The script script/custom.ps1

The file provisioner tells packer to copy our custom PowerShell script into the VM.

The next thing we did, was right before script/clean.bat, we told packer to run custom_launcher.bat. custom_launcher.bat is a helper script that launches PowerShell to run custom.ps1, and is a simple one-liner:

Powershell.exe -executionpolicy Unrestricted -Command "& c:\Windows\Temp\custom.ps1"

Note: We use the helper script approach because the PowerShell provisioner assumes the use of WinRM, which didn’t work out of the box on OSX Sierra. If you are using Windows to run packer, you can use the PowerShell provisioner instead.

Finally, the contents of custom.ps1 are here:

If you’re paying attention, the above script is just a consolidated version of the work from here.

Build the VM

Now that you have all the bits together, it is time to build the VM. From the command line, run the following command:

$ pwd
/Users/bunchc/projects/packer-templates/windows

$ make vmware/eval-win10x64-enterprise-ssh

After a long while and a LOT of output, you will have a shiny Win10 VM vagrant box with Java installed, so you can well, access that one iLO board on that one box that you can’t turn down, because ‘reasons’.

Note: To enable debug logging, you can run the make command like this: PACKER_LOG=1 make vmware/eval-win10x64-enterprise-ssh

Use the VM

I had thought to leave this step as an exercise for the end user. Why? Because, while packer will give you a Vagrant box by default, you can also output this directly into vSphere for use that way. What we’ll do here, for those unfamiliar with Vagrant, is build a minimal Vagrant file and fire up the VM:

vagrant box add \
    -name Win10x64 \
    ./box/vmware/eval-win10x64-enterprise-ssh-nocm-1.0.4.box

mkdir -p /projects/Win10-x64

cd /projects/Win10-x64

vagrant init -m Win10x64

vagrant up --provider=vmware_fusion

Cleanup & Rebuilding

Ok, so you logged into whatever thing you needed the Win10VM for, did a bunch of work, and now want the free space back:

cd /projects/Win10-x64

vagrant destroy -f

vagrant box remove Win10x64

cd /projects/packer-templates/windows

make clean

To rebuild, rerun the make command, which should pull in all the updates and what not that you need.

On Computerized Note Taking

I have blogged on and off about note taking, their importance, some random techniques and such. After a year or two of trying /LOTS/ of different tools, techniques, and the like, I thought I’d share the current method that has stuck for me.

This post is going to be rather long, so: tl;dr - Rakefile with templates, markdown formatted, auto-saved to an personal gogs server.

This post has four parts:

  • How I got here
  • The types of notes I take
  • My current process
  • The Tools

How I got here

The long and short of this story, is I missed the days of putting .LOG into Windows notepad and having it timestamp on each file open. Couple that with what is formerly Google Desktop search, and you had all of your notes, right there, indexed and with easy access.

This is not a knock on Evernote and other tools of the like. I tried just about every one of them. Along with easy searching, version control, and all the other good stuff, I gain a few extra benefits: easy transition to blog posts (commit to a different repo), easy export as static html or PDF for others consumption (using pandoc).

The Types of Notes

When taking notes on the computer, there are three basic types I take:

  • Case-Notes
  • Call-Notes
  • Draft Posts

Case-Notes

These are analogous to project notes and are the most generic form of notes I take. The template for these looks like this:

Customer:    Orangutan Roasters
Project:     Burundi Roast
Author:      Your Name
Date:        2017-04-17
categories: 
---
  
# Orangutan-Roasters

Some background here
# Burundi Roast

Some background here
# Notes:

The information at the top is metadata, which wile searchable, does not get exported to PDF. It then includes two sections to provide background information about the task, customer, project, you name it. This is useful for context setting. Finally, you have a heading for freeform notes. Here I add timestamps as I go, so I have a running log of what I am doing and some context to return to.

Call-Notes

Any time my phone rings, I take notes. This way I have a reference point of who I called, when, what about, etc. All the stuff you’d get from a recorded call, but you know, searchable. The template for that looks like this:

---
Subject:     Orangutan Roasters at Farmers Market
Customer:    Orangutan Roasters
Project:     Cottage Food Sales
Author:      Not Me
Date:        2017-04-17
categories: 
---
# Background

The context of the call goes here.

# Call details:
Organiser:   Not Me
Bridge:      1-800-867-5309,,112233#

On the call:
* 

# Unformatted notes:

Start taking notes here

Much like the more generic case-notes, the bits at the top are metadata that do not get exported, but are useful for finding this again later. Additionally, when using rake to create the template file, you can supply the call bridge for easy copy-paste later.

The Tools

There are a few tools used here:

  • Rake / Rakefile - Provides the template used for the different note / blog types
  • Sublime Text - My editor of choice
  • The Git and GitAutoCommit modules for Sublime - Version history
  • pandoc module for Sublime - Easy export to Word, PDF, or HTML

Organization

As you will see reflected in the Rakefile that follows, I keep my notes in a bit of a tree structure:

$ tree
.
├── Rakefile
├── call-notes
    └── 2017-04-13-pest-control.md
└── case-notes
    ├── 2017-03-02-home-scratch.md
    ├── 2017-03-02-work-scratch.md
    └── 2017-04-13-home-networking.md

The drafts for blog posts live in their own tree. As long as you specify the path in the Rakefile, you can store your notes anywhere.

The Rakefile

The rakefile I use to create notes currently has three sections, one for each type of note I take most regularly: Blogs (:post), Project (:note), and Call (:call)

To create a new note, from the command line one runs rake notetype parameter="thing". For example, if I wanted to open a new file for a coffee roast I would use a command like this:

rake note customer="Orangutan Roasters" project="Buruni Roast"

Which creates a file named similar to 2017-04-17-Orangutan-Roasters-Burundai-Tasting.md and which contains the following template text:

Customer:    Orangutan Roasters
Project:     Burundi Roast
Author:      Your Name
Date:        2017-04-17
categories: 
---
  
# Orangutan-Roasters

Some background here
# Burundi Roast

Some background here
# Notes:

Now that you have the template file in place, you can open in an editor of your choice, and markdown being super close to plain text, you’re off and going.

Sublime Text

My editor of choice. Yes yes, I know I can do these things in vimacs or whatever and to each their own.

To install Sublime on OSX:

brew install Caskroom/cask/sublime-text3

This in turn links the subl command to /usr/local/bin/subl. This allows you to open notes as follows:

subl case-notes/2017-04-17-Orangutan-Roasters-Burundai-Tasting.md

Sublime Modules

As discussed above I use the Git, GitAutoCommit and pandoc modules. These can each be installed using their specific instructions. I’ve linked those here:

Once you have those, these minor config tweeks will save you some heartache. For Pandoc, in your user-settings (Click sublime, Preferences, Package Settings, Pandoc, Settings - User), paste the following in:

    {
      "default": {

           "pandoc-path": "/usr/local/bin/pandoc",

        "transformations": {

          "HTML 5": {
            "scope": {
              "text.html.markdown": "markdown"
            },
            "syntax_file": "Packages/HTML/HTML.tmLanguage",
            "pandoc-arguments": [
              "-t", "html",
              "--filter", "/usr/local/bin/pandoc-citeproc",
              "--to=html5",
              "--no-highlight",
            ]
          },

          "PDF": {
            "scope": {
              "text.html": "html",
              "text.html.markdown": "markdown"
            },
            "pandoc-arguments": [
              "-t", "pdf",

              "--latex-engine=/Library/TeX/Root/bin/x86_64-darwin/pdflatex"
            ]
          },

          "Microsoft Word": {
            "scope": {
              "text.html": "html",
              "text.html.markdown": "markdown"
            },
            "pandoc-arguments": [
              "-t", "docx",
              "--filter", "/usr/local/bin/pandoc-citeproc"
            ]
          },

        },
        "pandoc-format-file": ["docx", "epub", "pdf", "odt", "html"]

      }

    }

To export using Pandoc, ‘command + shift + p’, then type ‘pandoc’, press enter and select how you want to export it.

The Process

If you are still with me, thanks for sticking around. Now that all the scaffolding is in place, to create a new note, from the root of the notes folder:

$ rake call subject="Orangutan Roasters at Farmers Market" customer="Orangutan Roasters" project="Cottage Food Sales" bridge="1-800-867-5309,,112233#" owner="Not Me"

$ subl call-notes/2017-04-17-Orangutan-Roasters-Orangutan-Roasters-at-Farmers-Market.md

And you’re off.

Summary

Well, this ended up being much longer than I had expected, however, at the end of it all, you have notes that are versioned and backed up to git, and are searchable with grep or any tool of your choice.

Enable Bonjour on UBNT USG-4P

This here is super hacky, but it works.

Problem:

After segmenting the home network (kids, guest, random iot devices, etc), Bonjour stopped working.

Solution

The proposed solution is to SSH to the Security Gateway and run the following:

configure
set service mdns reflector
commit
save
exit

This works, great! Right? The problem with the above method, is that you are broadcasting your stuff out on the WAN Interface. I don’t know about you, but I don’t like the idea of what might show up on my AppleTV.

A better solution:

We start as prescribed. This makes sure the right services are installed and the config files are in place:

configure
set service mdns reflector
commit
save
exit

Now, undo that:

configure
delete service mdns
commit
save
exit

Now, edit /etc/avahi/avahi-daemon.conf with your corresponding interfaces. The relevant sections of my file look like this:

[server]
...
allow-interfaces=eth0,eth0.20,eth0.40,eth0.50,eth0.60
...

[reflector]
enable-reflector=yes

Finally, we add a script to ensure these services start on reboot & start them now:

echo "#!/bin/bash -
#title          :bonjour-fix.sh
#description    :Starts dbus and avahi on reboot on the USG-4P
#============================================================================

for service in dbus avahi-daemon; do {
    if (( $(sudo ps -ef | grep -v grep | grep "${service}" | wc -l) > 0 )); then {
        echo "[+] ${service} is running"
    } else {
        echo "[i] Attempting to start ${service}"
        sudo /etc/init.d/"${service}" start
    } fi
} done" | sudo tee /config/scripts/post-config.d/bonjour-fix.sh

sudo chmod +x /config/scripts/post-config.d/bonjour-fix.sh

sudo /etc/init.d/dbus start
sudo /etc/init.d/avahi-daemon start

Resources

This solution was put together from a number of forum posts:

Building a Lab AD with PowerShell

Remember that post where we installed and built an Active Directory domain with PowerShell and BoxStarter?

Well, Domains are cool and all, but are generally uninteresting all by themselves. To that end, you can adapt the script and CSV files found here to populate your domain with some more interesting artifacts.

For me, I incorporated this into my existing BoxStarter build, so all I have is the one command to run, the script is below:

You’ll notice, as compared to before, we’ve added some lines. Specifically:

  • Lines 24 & 25 pull down all the files and extract them
  • Lines 28 - 30 allow us to run internet scripts, change our working directory, and finally run our script.

As before, to launch this on a fresh Windows install:

START http://boxstarter.org/package/nr/url?https://gist.githubusercontent.com/bunchc/b7783fd220b5602cffc46158bac3099e/raw/a3e6b58904efb06953130112f98a5382cff7dc20/build_and_populate_domain.ps1

Once completed your script window will look similar to: PowerShell script output

And AD will look like this: AD Users and Computers

Building a Windows Domain with BoxStarter

I had a need to create and recreate Windows domains for some lab work I’ve been up to. What follows here is adapted from @davidstamen who blogs here. More specifically it is extracted from his Vagrant Windows lab, here.

Warning! Boxstarter is sort of like curl pipe sudo bash for Windows.

First things first, look over what we’re doing:

What is going on here?

  • The first two lines contain the domain name you’d like configured.
  • Lines 4 & 5 make Explorer a bit less annoying and enable remote desktop (if it’s not already).
  • Lines 7 - 15 install some useful packages
  • Line 18 enables AD
  • Line 22 installs the domain.

All of that is simple enough. The magic comes in when we use boxstarter to go from a new Windows Server to Domain Controller. From an admin command prompt on the Windows server, run the following:

START http://boxstarter.org/package/nr/url?https://gist.githubusercontent.com/bunchc/1d97b496aa1d6efe146f799b2fb34547/raw/51ebf18ca320c49c38e2f493e0ff4afad59bb0cd/domain_controller.ps1

Note: You may need to add boxstarter.org to trusted sites.

Once executing, it should look a bit like this:

BoxStarter Domain Installation