Poison

Today I found out that a good friend of mine quit Facebook. I was astounded -- he had just been filled with such righteous indignation about the election, and big ideas about the change that we needed to bring about. How could he bring about that change if he removed the best tool for talking to people?

But the more we talked, the more convinced I was that he had it right.


On the night of the election, Stephen Colbert talked about poison:

You take a little bit of it so you can hate the other side. And it tastes kind of good. And you like how it feels. And there's a gentle high to the condemnation, right? And you know you're right, right? You know you're right.

Social media is at the center of this. Facebook is designed to give you this high. It is designed to give you exactly what you want to see/hear, because that keeps you coming back and lets them serve you more ads.

We craft echo chambers for ourselves. We are increasingly convinced we are right and the other side is wrong, and if we ever do happen to come in contact with someone from the other side, we talk past each other until we're blue in the face. Anger and indignation prevail, reason and empathy fail.

In the last three days I've seen very few productive conversations happening on social media. We try to empathize, we try to make our points. But without the human connection of one-on-one communication, we make no progress. We high five those that agree with us and ignore those who don't. We may not even realize we're ignoring anyone -- the Facebook algorithm is making that choice for us.

TechCrunch says the Facebook bubble just popped. They're right. Read that story, and realize the dangers of the echo chamber. Facebook does more harm than good.


In his last post before quitting Facebook, my friend Mike made some cogent points about our rejection of fact in favor of our echo chambers:

After a century of prosperity, we started to believe that we knew better than what newspapers told us, or scientists told us, or economists told us. We stopped believing in classical books by great thinkers and started believing in podcasts. In even the best cases, we fired articles at each other instead of arguments. What’s more, we thought that our skepticism of expertise was the fault of the expert and not our own. We built the Internet in hopes that it would foster the greatest exchange of ideas in human history. Hopes of that nobility have been diminished.

This election is a lot of things but above all, it’s cultural hubris boiled over.

He goes on to talk about our rejection of fact-based media in favor of our little social media worlds:

Collectively, we rejected newspapers, nearly bankrupted them and then wondered what happened to the fourth estate. I’m not so sure that we should be as outraged as ashamed.

One of my favorite quotes:

If you are unwilling to accept facts that do not align with your view of reality, you are the most dangerous kind of coward.

But Mike doesn't leave us without a call to action.

So, if you want to be angry, be angry — for a while, at least.

When you’re done, though, go out and buy a newspaper subscription to every single publication that you can afford to support. Do this not just for papers which lean in your direction but any paper which has reputable, hard-working reporters who are dedicated to shining a light where it needs to shine. Read all of them. Every day.

When they report the facts, accept them as facts — not as a hypothesis which has its truth contingent on the institution which presented it.

And, too, when they editorialize, accept that as opinion from people who understand the world in a sophisticated way. Admire that sophistication, even if you do not agree with its conclusions.

Do not conflate facts and opinions. Even if you are wrong five percent of the time and bias sneaks into reporting, accept it and move on. Stop throwing babies out with bathwater.

Finally, find a friend, if you can, and see where there might be common ground to stand on.

The waters rise fast and we only survive if we hold on to each other.

Stronger together.


Last night I spent a solid two hours talking to two of my best friends while we ate tacos after playing basketball. It was a productive, respectful conversation. I learned things and grew, and we didn't just talk past each other. Granted, this was helped by the fact that we have similar views, but it was refreshing all the same.

I want more of those nights. I want to have smaller, real conversations with people. I want to learn and grow. I want to be more than just retweets and likes.


So here's my plan: I plan to get back to my subscription to The Economist and The Washington Post. I plan to read fact-based reporting and editorializing and form my own opinions.

But as importantly, I have to get out of my echo chamber. And I'm less and less willing to feed into the machine that caused this: Facebook.

In a few days, after most people who will see this post have seen it, I will likely disable my Facebook account.

Twitter is harder. I love Twitter: It's the poison I crave. But I think it has to go as well, at least for awhile. So I'll be taking a break.

But that doesn't mean that I don't want to talk. In fact, I want to talk more than ever. But I don't want to do it on Facebook or Twitter.

Call me. Text me. Let's go grab a drink (soda for me) or some lunch and chat. Let's make real relationships, and have real conversations.

And let's stop drinking the poison.

colton.myers@gmail.com // 801-999-8328

Hate

Trump gave a surprisingly presidential victory speech:

I mean, she fought very hard. Hillary has worked very long and very hard over a long period of time, and we owe her a major debt of gratitude for her service to our country.

I mean that very sincerely. Now it is time for America to bind the wounds of division, have to get together. To all Republicans and Democrats and independents across this nation, I say it is time for us to come together as one united people.

Hopefully this is the Trump that will enter office as our next president.

Today I'm less worried about Trump as president than I am about the hate, mistrust, racism, and sexism that his campaign made mainstream. He validated monstrous behaviors.

Read every story in that link. Think about what it would be like to live in fear of the people around you.

As a straight white male, I'm blessed with safety from acts like this. I will wield that safety in defense of those who are not. I won't allow casual or joking racism. If I see someone being harassed, I will step in. I will serve and love those around me. And I will pray for those who are living in fear today.

Will you join me?

American

Tonight I am embarrassed to be an American.

For much of my life I identified as a Republican. In the last few years I've found myself identifying less and less with that party. Not to say I'm a Democrat; both parties have serious problems.

This year I voted for Hillary. Not because she was the lesser of two evils. She's far from perfect, and I don't agree with her on everything. But she's an accomplished politician and a qualified presidential candidate. I like the strength with which she has dealt with Trump's attacks. I voted for her because I'm With Her.

This is probably not a popular opinion. But I'm trying to be true to my opinions rather than just hiding behind the "Trump is a monster" argument.

Tonight America chose hate, mistrust, racism, misogyny, and violence. Tonight I am embarrassed to be an American.

Check Out the Packt Free Learning Campaign!

Packt is running a cool promotion right now where you can get a different free ebook each day until a March 5. Check it out!

My Book is Available!

My book, Learning SaltStack, is available for purchase!

It's available in paperback, as well as for kindle from Amazon.

You can also buy it directly from Packt.

Hope you enjoy it!

Mitigating GHOST with SaltStack

My coworker CR wrote up a great guide to mitigating the new GHOST vulnerability with SaltStack.

Check it out here: Mitigating GHOST with Salt

If you haven't already checked out SaltStack, I highly recommend it! You'll never have to manually patch all of your machines again!

The Problem with the Hobbit Movies

I was catching up on my RSS feeds and I found [this review of the last Hobbit movie by Ars Technica][1]. Sums up my feelings perfectly:

There's one big thing that doomed these movies from the outset—the fiscally smart but artistically bankrupt decision to make a single, shortish children's novel into three feature-length prequel films.

Artistically bankrupt. Perfect way to put it.

What these movies desperately need are boundaries, reasons to condense scenes or cut them out entirely instead of reasons to pile on more. Chopping these down into a pair of two-and-a-half hour movies would drastically improve the pacing even if you didn't address the characterization or the tone issues. You could leave around three hours of slow-motion action sequences, goblin chases, and Radagast the Brown on the cutting room floor! Sounds great, doesn't it?

Couldn't have said it better myself.

Fix Linode Manager Repeated Log-out (Force IPv4)

Recently I've been having issues with Linode Manager repeatedly logging me out every few requests. I figured this was related to ipv4/ipv6 switching, because sometimes the logout would also trigger a new IP whitelist request, which would sometimes be ipv4, and sometimes be ipv6.

After a little googling, I found this twitter conversation:

Turns out I'm not the only one experiencing this issue. So I decided to set up dnsmasq as one of the replies mentioned, and force Linode to a single ipv4 address.

Note that these instructions are for OSX (and were tested on Yosemite, 10.10).

First, I installed dnsmasq via Homebrew:

brew install dnsmasq

Then, I followed the homebrew instructions to install dnsmasq as a service to start on startup:

sudo cp -fv /usr/local/opt/dnsmasq/*.plist /Library/LaunchDaemons
sudo chown root /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist

Now, before we actually start the service, let's get our resolver in place. OSX allows us to define resolve data for specific addresses using files in /etc/resolver/. Here is my /etc/resolver/manager.linode.com:

nameserver 127.0.0.1

Basically, we're telling the operating system to use our local DNS server (provided by dnsmasq) for lookups for manager.linode.com.

We also need to configure dnsmasq to force manager.linode.com to a specific address. First, we need an IPv4 address to work with:

# dscacheutil -q host -a name manager.linode.com
name: manager.linode.com
ipv6_address: 2600:3c00::14
ipv6_address: 2600:3c00::34
ipv6_address: 2600:3c00::24

name: manager.linode.com
ip_address: 69.164.200.204
ip_address: 72.14.191.204
ip_address: 72.14.180.204

Then, copy the example configuration into place:

cp /usr/local/opt/dnsmasq/dnsmasq.conf.example /usr/local/etc/dnsmasq.conf

and edit /usr/local/etc/dnsmasq.conf, adding this line:

address=/manager.linode.com/72.14.180.204

Now, start dnsmasq:

sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist

Assuming you did everything right, you should only see one address when you query again:

dscacheutil -q host -a name manager.linode.com
name: manager.linode.com
ip_address: 72.14.180.204

I haven't done much on Linode since implementing this fix, but haven't had it log me out erroneously once yet.

If you have improvements or run into issues, please leave a comment below!

Blog Auto-Publish with Dropbox

This weekend I moved my blog over to Pelican from Octopress. I've been very happy with this decision.

But I decided I wanted to go a step further, and set up autopublish. I knew it could be easily done with a git hook, but I wanted to be able to easily blog from my iOS devices as well, so I decided to go with Dropbox instead.

Getting Dropbox

First, I needed to install Dropbox on my machine. Dropbox provides an easy one-liner:

cd ~ && wget -O - "https://www.dropbox.com/download?plat=lnx.x86_64" | tar xzf -

Now, when I first tried to start up dropbox, it gave me a cryptic error, which I traced back to not having X11 libraries installed. Turns out I just needed to unset my DISPLAY variable:

unset DISPLAY

Now Dropbox will start properly:

~/.dropbox-dist/dropboxd

Follow the instructions to get Dropbox authorized on your server, then once you see the success message, exit using ctrl-c.

Configure Dropbox as System Service

Next we need to create an init script for Dropbox. I found an example here. Here's the Ubuntu/Debian script:

#!/bin/sh
#dropbox service
DROPBOX_USERS="user1 user2"

DAEMON=.dropbox-dist/dropboxd

start() {
   echo "Starting dropbox..."
   for dbuser in $DROPBOX_USERS; do
       HOMEDIR=`getent passwd $dbuser | cut -d: -f6`
       if [ -x $HOMEDIR/$DAEMON ]; then
           HOME="$HOMEDIR" start-stop-daemon -b -o -c $dbuser -S -u $dbuser -x $HOMEDIR/$DAEMON
       fi
   done
}

stop() {
   echo "Stopping dropbox..."
   for dbuser in $DROPBOX_USERS; do
       HOMEDIR=`getent passwd $dbuser | cut -d: -f6`
       if [ -x $HOMEDIR/$DAEMON ]; then
           start-stop-daemon -o -c $dbuser -K -u $dbuser -x $HOMEDIR/$DAEMON
       fi
   done
}

status() {
   for dbuser in $DROPBOX_USERS; do
       dbpid=`pgrep -u $dbuser dropbox`
       if [ -z $dbpid ] ; then
           echo "dropboxd for USER $dbuser: not running."
       else
           echo "dropboxd for USER $dbuser: running (pid $dbpid)"
       fi
   done
}

case "$1" in

   start)
       start
       ;;
   stop)
       stop
       ;;
   restart|reload|force-reload)
       stop
       start
       ;;
   status)
       status
       ;;
   *)
       echo "Usage: /etc/init.d/dropbox {start|stop|reload|force-reload|restart|status}"
       exit 1

esac

exit 0

Note that when I pulled down that script originally, it had a typo. The DAEMON line near the top of the file should be .dropbox-dist/dropboxd -- they left off the trailing d in the version I downloaded.

Place this script in /etc/init.d/dropbox. Replace the DROPBOX_USERS setting with a space-separate list of users for which you want Dropbox running. Then, make the file executable and set it to execute on startup:

sudo chmod +x /etc/init.d/dropbox
sudo update-rc.d dropbox defaults

Now, start Dropbox again, as a service:

sudo service dropbox start

Selective Sync (Optional)

I have a very large Dropbox folder, and so only want to sync the Blogs folder from my Dropbox account.

I downloaded the CLI script mentioned on that installation page:

wget https://linux.dropbox.com/packages/dropbox.py

Then, with Dropbox running, I excluded all the directories within the Dropbox folder, then removed the Blogs folder from the resulting exclusion list:

./dropbox.py exclude add ~/Dropbox/*
./dropbox.py exclude remove ~/Dropbox/blogs

Perfect, now I have only my blogs syncing to my server's dropbox folder.

Autopublish: The Watcher Script

The automagic regeneration of my blog I modified from this post.

I'm going to assume you have a working Pelican setup. Assuming you used the Pelican quickstart, you should have both a pelicanconf.py and a publishconf.py. The publishconf.py is going to be what we use.

First, you must modify your publishconf.py file such that it can operate from any directory, rather than relying on relative paths. Thus, you should add your blog's absolute directory to the Python path inside of that script. Here is my publishconf.py:

#!/usr/bin/env python
# -*- coding: utf-8 -*- #
from __future__ import unicode_literals

# This file is only used if you use `make publish` or
# explicitly specify it as your config file.

import os
import sys

#sys.path.append(os.curdir)
# This is the directory where your pelican's
# configuration files reside
pelicanpath = '/home/basepi/Dropbox/Blogs/blog.basepi.net'
sys.path.append(pelicanpath)

sys.path.append(os.curdir)
from pelicanconf import *

SITEURL = 'http://blog.basepi.net'
RELATIVE_URLS = False

FEED_ALL_ATOM = None
CATEGORY_FEED_ATOM = None

DELETE_OUTPUT_DIRECTORY = True

These are the key lines:

pelicanpath = '/home/basepi/Dropbox/Blogs/blog.basepi.net'
sys.path.append(pelicanpath)

Now no matter what my current working directory is, the publishconf.py will be able to find the files it needs to operate.

Next, I created a publish script, publish.sh:

#!/bin/bash

PELICAN=/usr/bin/pelican
CONTENT=/home/basepi/Dropbox/Blogs/blog.basepi.net/content
OUTPUT=/home/basepi/Dropbox/Blogs/blog.basepi.net/output
SETTINGS=/home/basepi/Dropbox/Blogs/blog.basepi.net/publishconf.py

rm -rf /home/basepi/Dropbox/Blogs/blog.basepi.net/output/*
$PELICAN $CONTENT -o $OUTPUT -s $SETTINGS || exit $?
rsync -r --delete /home/basepi/Dropbox/Blogs/blog.basepi.net/output/ /var/www/blog.basepi.net

Note the use of || exit $?. This will cause the script to exit if the retcode of the pelican command is non-zero. I don't want to publish my blog if there are problems.

Make this script executable, and then run it to test that things are working.

The final step is to set up the watcher script which will run our publish script on changes. For this purpose we will be using this watcher script.

This script, conveniently, is ready to be used as an init script. Take the script and put it at /etc/init.d/watcher. Make it executable:

sudo chmod +x /etc/init.d/watcher

Now, we need to create the configuration file for the watcher. This file is at /etc/watcher.ini:

[DEFAULT]

; where to store output
logfile=/var/log/watcher.log

; where to save the PID file
pidfile=/var/run/watcher.pid

[job1]
watch=/home/basepi/Dropbox/Blogs/blog.basepi.net/content
events=modify,create,delete,move
excluded=
recursive=true
autoadd=true
command=/home/basepi/Dropbox/Blogs/blog.basepi.net/publish.sh

Now we just need to start the watcher:

sudo service watcher start

You can tail the log to see if it's working (change a file to trigger it):

tail -f /var/log/watcher.log

If everything is in order, just have the watcher start on boot:

sudo update-rc.d watcher defaults

And you're done! Now, any time you change the content of your blog, it will be automatically re-built and published for you!

Let me know what you think in the comments. Or hit me up on Twitter!

Tagged , , , ,