Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: essay

  • “Oh yeah. That’s a bug.”

    “Oh yeah. That’s a bug.”

    “You’ve been saying you’re working on it for two years! How hard could it be?”

    The post made my blood pressure rise a little. I was uncharitable, in my own mind, thinking Well if you know how to do it, why don’t you get off your whingy ass and do it? I was snippy, I was snide, I was … let’s face it, I was mean.

    But I didn’t say it out loud. I stood up from the laptop and played a round of ping pong with a coworker who is a bazillion times my better (seriously, he’s great) and tried to learn to return spin-serves. I still can’t, but I understand them now. Then, refreshed, I went back and replied.

    “I know it sounds really dismissive, but there are more things at play then just slapping a new coat of paint on the system. We have to take into account the following things [list]. On top of that, we have to do it all in a way that won’t crash the system and that’s backwards compatible!”

    I looked at that for a moment and I sighed. No matter how I explained it, no matter which language I used to demonstrate the complications, the reply was still going to be ‘Don’t make an excuse, just fix it.’

    Complex art

    There’s a weird truth about software and development that is the people writing or fixing the code generally don’t get fired up about it in a reactionary way. That’s not to say they’re not passionate, or that I never see them angry or excited, but that they’re sort of a Cool Hand Luke about a lot of things, including their job.

    From 1997 to 2012, I worked at a bank. I tapped out just shy of 15 years, and through that time I went from desktop applications to operating systems to server based desktop applications (remote apps) to server deployment. I did a lot. I worked on everything, but I was never what you’d call ‘tech support.’ I did support for developers for about 5 years. At one point, when I was working on the OS side of things, my manager asked if I could help one of the senior VPs with an email issue. I agreed, went to his computer, looked at it, calmly minimized the app, fixed the resolution (yes), and was about to go when they screamed.

    “You closed my email!”

    I blinked a few times, clicked on maximize, and pointed out I had only minimized it.

    My manager apologized for over-reacting, but suggested next time I maximize before I leave the desk. I did not point out that what I was doing was not in my job description at all, but I did agree he had a point and said that I would be sure to leave the PC the way I found it, except fixed. This lesson stayed with me. When I fix your site, I try to leave it the way YOU wanted it.

    The next day I had a complaint land in my lap, from the Sr.VP, that I didn’t take the issue serious enough. This was tacked on to the heels of another incident that, at the time, I’d forgotten about, where a server went down, people flipped out and called me, and I said “Uh huh, I see what’s wrong. *type* There we go. All better, I’ll fill in the ticket. Sorry about that.”

    What was this complaint? I was too cavalier.

    I did argue that complaint, and ‘won’ as much as anyone can, because I noted you don’t want the panicking person to run around and scream when they fix your broken stuff, you want them to be calm and collected. At the same time, I did learn something important, and that is people need to feel that you do empathize with them and feel their pain. I’m much better at that now than I was in 2001, but in the last thirteen years, I’ve blown my site up enough to know that level of terror in a visceral way.

    But for the person who is having the horrible, no good, very bad, day, there’s a lesson for you too! Sometimes when someone says “Yes, we know.” or “Yes, we’re fixing that.” they can sound far more calm and casual than you are, to the point where they seem dismissive, not because they are dismissive, but because of their experiences. It’s the same logic behind anyone who handles high-stress situations regularly: we get used to it, and we have managed to overcome our panic.

    What does all this have to do with the time you asked for a change and we said “We’re working on it?” We’re calm because we are working on it. We sound dismissive because we’ve said many times we’re working on it. We know we don’t have an answer and how much that sucks, but we know (and you know in your heart) that yelling at people to fix it now has never, in the history of ever, actually made someone come to that genius moment faster. Even critical bugs, like Heartbleed, are things everyone tries to fix as soon as possible, but not in a rush or a panic. And if they’re not critical, then we’re generally not going to rush and fix it unless we’re certain we can do it in a way that is safe for everyone, sustainable, and we agree with it.

    That sounds like a lot, and it also sounds like an excuse. It’s not. If someone replies “Yes, we’re working on it.” it’s okay for you to ask “Is there anything I can do to help?” It also means you may have to accept that some annoyances are going to stick around for a long time, because they’re complicated, or maybe they require a total rewrite. But as long as they’re communicating with you, they’re not ignore you.

  • Local Backups

    Local Backups

    You heard about CodeSpaces didn’t you?

    On June 17th they got hit with a DDoS. It happens. On June 18th, the attacker deleted their data. And the backups. Because the backups were on the same server… You can read the story here and make up your own mind.

    But that brings us to this. Are you making your own, personal, backups?

    My server makes entire server backups every day and collocates them, but I also have my own backups of my own, personal, data. Not my email. If that blew up today I would lose nothing I can’t get back. That’s right, I don’t keep much email. If it’s important, I store it on my laptop, on iCloud or Dropbox, and I backup my laptop to TimeMachine. Oh and I check that backup regularly.

    So how do I backup my sites? It’s three fold.

    Clouds and Fences

    On the Server

    I use a DB script from Daniel D Vork. He backs up files to DropBox, which is cool, but for me, I have this script on my server and it stores to a non-web-accessible folder called ‘backups’:

    #!/bin/bash
     
    USER="your_user"
    PASSWORD="your_password"
    OUTPUT="/Users/YOURUSERNAME/backups"
     
    rm "$OUTPUT/*gz" > /dev/null 2>&1
     
    databases=`mysql --user=$USER --password=$PASSWORD -e "SHOW DATABASES;" | tr -d "| " | grep -v Database`
     
    for db in $databases; do
        if [[ "$db" != "information_schema" ]] && [[ "$db" != _* ]] ; then
            echo "Dumping database: $db"
            mysqldump --force --opt --user=$USER --password=$PASSWORD --databases $db > $OUTPUT/`date +%Y%m%d`.$db.sql
            gzip $OUTPUT/`date +%Y%m%d`.$db.sql -f
        fi
    done
    

    That script is called every day at midnight via a cron job.

    Bring it local

    On my laptop, under the ~/Sites/ folder, I have a folder for each domain. So there’s one for ipstenu.org (which is where this site lives), and in there are the following:

    backup-exclude.txt       backup.sh          log.txt
    public_html/
    

    The public_html folder is a full backup of my site files. It’s not that crazy, don’t panic.

    The backup.sh file does an rsync:

    #!/bin/sh
    
    cd $(dirname $0)
    
    TODAY=$(date)
    echo "
    -----------------------------------------------------
    Date: $TODAY
    Host: ipstenu.org hosted sites
    -----------------------------------------------------\n" > log.txt
    
    echo "Backup files..." >> log.txt
    rsync -aCv --delete --exclude-from 'backup-exclude.txt' -e ssh backups@ipstenu.org:/home/ipstenu/public_html/ public_html > log.txt
    
    echo "\nBackup databases..." >> log.txt
    rsync -aCv --delete --exclude-from 'backup-exclude.txt' -e ssh backups@ipstenu.org:/home/ipstenu/backups/ databases >> log.txt
    
    echo "\nEnd Backup. Have a nice day." >> log.txt
    

    Backups is not the name of the account but I do have a backup only account for this. The backup-exclude.txt file it calls lists folders like ‘cache’ or ‘mutex’ so I don’t accidentally back them up! It’s simply just each file or folder name that I don’t want to backup on it’s own line. And yes, I like pretty output in my logs so I can read them when I’m having a brainless moment.

    The cd $(dirname $0) at the beginning is so that I can call this from other folders. Remember! If your script uses relative paths to access local resources, then your script will break if you call if from another folder. This has a reason why in the next section.

    Automate that shit!

    I’m on a Mac. I decided I wanted that backup to run every time I logged in to my computer. Not rebooted, logged in. And waking from sleep. That became problematic, but let’s get into this code.

    Writing the scripts

    First I made a new folder called ~/Development/backups and I’ll be stashing my code there. In there I have a couple files. First is website-backup.sh:

    #!/bin/sh
    
    /Users/ipstenu/Sites/ipstenu.org/backup.sh
    /Users/ipstenu/Sites/othersite.net/backup.sh
    

    Basically for every site I want to run backup for, it’s in there. This is why I have the change-directory comment on the backup scripts.

    The other file is my launchd file, called com.ipstenu.website-backups.plist and I got this code from stackexchange:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
       <key>Label</key>
       <string>com.ipstenu.website-backups</string>
       <key>Program</key>
       <string>/Users/ipstenu/Development/backups/website-backup.sh</string>
       <key>RunAtLoad</key>
       <true/>
    </dict>
    </plist>
    

    Instead of copying the file, though, I did a symlink:

    ln -sfv /Users/ipstenu/Development/backups/com.ipstenu.website-backups.plist ~/Library/LaunchAgents
    

    This lets me change it if I need to, which I doubt I will. I’ll just edit that .sh script. The filename of the plist is intentional to tell me what the heck it is.

    But wait, what about waking from sleep? Logging in from a sleeping computer is not the same as a log in to a Mac, and there’s no built in tool to monitor sleep and wake for some reason. There are apps that can do it, but there’s also SleepWatcher, which can be installed via Brew! Since I’m running an rsync, it’s not a big deal to run multiple times a day. Heck it may actually be faster.

    First we install Sleepwatcher:

    brew install sleepwatcher
    

    Now Sleepwatcher looks for user scripts named ~/.sleep and ~/.wakeup which sure makes my life easier. My ~/.wakeup file calls website-backup.sh, and while I could have it repeat the code, I chose not to for a reason. I know my backup scripts will live in ~/Development/backups/ so I can add a new one for something else without messing around with more than one file.

    Do you remember launchd a moment ago? We want to use that again to tell Sleepwatcher it’s okay to run on startup or login. This time, since we’re only using Sleepwatcher for sleep and wake, we can symlink the sample files to the proper LauchAgents directories. In my case, it’s only running for me, so it’s all local:

    ln -sfv /usr/local/Cellar/sleepwatcher/2.2/de.bernhard-baehr.sleepwatcher-20compatibility-localuser.plist ~/Library/LaunchAgents
    

    If you’re interested in doing more with sleepwatcher, read Mac OS X: Automating Tasks on Sleep by Kodiak.

    Finally we’re going to load both of these commands into launchctl:

    launchctl load ~/Library/LaunchAgents/com.ipstenu.website-backups.plist
    launchctl load ~/Library/LaunchAgents/de.bernhard-baehr.sleepwatcher-20compatibility-localuser.plist
    

    Now every time I log in on my laptop, it runs a backup, be that a real login, or a wake-from-sleep one.

    And remember, this is on top of my full server backups and my personal git repository for my code, so I have my data backed up in the important places. Everything on my laptop is backed up to the TimeMachine, so really I can just look back a year or three and find that html file I used once.

    The other thing I do is check these backups pretty regularly. I scheduled a day every month to check that everything’s working right, that the files are restorable, and that I feel secure. Thus far, the most I’ve lost has been 16 hours of work on a Wiki.

  • Yum!

    Yum!

    I’ve touched on it a couple times, and it’s related to why I love things like Homebrew, but I like package installers. While I can, and have many times, installed and packaged from source, it scares me and I don’t like it. When I talked about Homebrew, I mentioned in passing that I use yum to manage packages on my servers, and someone asked me “What’s that?”

    When I started this blog in 2009, the very first post was about understanding how to mess with my VPS and tweak it to work well with WordPress and everything else. In the five years since, I’ve learned a great deal about servers, tweaks, how to break things, but also how to upgrade them smartly. I’ve had struggles with SVN and GIT, but I understand that managing versions and revisions is a sane way to handle upgrades. But at the same time, not compiling code means I have more free time to mess with the stuff I like.

    This brings us to Yum.

    Yum is a software package manager manager, which means it checks various RPM Package Managers, sees if there is software you have that has an update, and updates it. An RPM Package Manager (or an RPM, yes, it’s a recursive acronym, just like PHP) stores packaged versions of code… I have a feeling someone’s looking at me like I spoke a new language.

    Let’s step back further. Your server is a computer and runs software. Most people have the experience of installing software via packaged installers (I used to make them for a living). When you download an app onto your phone, the phone downloads the package and runs the installer. This is similar to WordPress, right? You download the zip, unpack it, and run an installer. But your server, well, for a very long time people didn’t have installer packages, they had source code. The source code was downloaded, unzipped (hush, you know what I mean), compiled, and then installed.

    'Are you stealing those LCDs?' 'Yeah, but I'm doing it while my code compiles.'
    Credit: xkcd comic “Compiling”

    Yes, compiling code takes a long time. That joke is less funny than it is accurate to some of us. It’s not something most of us do any more, though, because code now tends to come pre-compiled, and that’s where package managers come into play. You see, someone realized that they could pre-compile code for all servers. It’s not the same code for all the servers, though, because there are so many flavors of servers, it’s mind boggling.

    But that said, if you know your flavor of server, you can use an RPM that matches to install software. So the RPM is like a massive server that has all the available installs for your server. When you add in yum, which installs the packages, you can then enter a world of automation where every night your server checks for new packages and installs them!

    Yum has a meaning. “Yellowdog Updater, Modified.” I didn’t say it was a good meaning. Yum has a bunch of obvious commands like “yum install NAME” and “yum update” which you can use to install extra add-ons like Memcached and so on. There are also yum utilities (yum-utils, which let you further customize automation by scripting commands.

    Just to touch on one at random, today I got an email from my server saying that it had run /usr/bin/yum -c /etc/yum.conf -y update for me. This is normal, I configured it to do that at midnight every day.

    There are unfinished transactions remaining. You might consider running yum-complete-transaction first to finish them.

    Now it did run the rest of the installs, so I did what any smart person does. I went and looked up this new command, only to find a string of bug reports from 2007-2009. It’s 2014, so I went and ran it once. It cleaned up one package and said I had another 244 left. Interesting. I ran it again. 243. I saw my day flash before my eyes and then decided to run the safer version:

    yum-complete-transaction --cleanup-only
    

    Safer and faster. Everything was cleaned, and update runs great now.

    Is there a risk with this automation? Of course! Which is why I take a backup every night, right before the update happens. I’m not crazy after all.

  • Not Everything is WordPress

    Not Everything is WordPress

    I touched on this when I talked about a project that forked, and I’ve said it before. I don’t use WordPress for everything, and I don’t think I should.

    A lot of you will probably disagree with me, especially since it’s well known much of what I love about WordPress is the fact that I don’t have to remove features. The problem is where WordPress started from has determined what kind of product it will be. But let me step back.

    When I spoke at WordCamp Miami, I said that the kind of WordPress user you are defines the future you will have with WordPress. What we are before WordPress is what makes us use it the ways we do, and the way we use it makes us who we are today. That makes sense, I hope. What we are is what makes us do what we do.

    So WordPress started as a blog. This means that no matter how many times we say “It’s a CMS and you can use it for anything!” it still shows blog at it’s heart. I use it for a store, it’s great at it, but there are aspects that remain bloggy. Similarly, MediaWiki was an ‘encyclopedia’ first, so while I know people who blog on it, it’s made for that cross-referencing. Certainly plugins can make these products fit the bill but at their base, you’re talking about the fundamental core of a product.

    Step back again.

    This is something I think is totally okay.

    I don’t buy a scooter and get upset it’s not a motorcycle. I don’t buy a tank and get upset that the Fiat has better gas mileage. I understand that each tool has its place, and while I certainly can tow a trailer with the Mini Coop, I’d rather use the truck. And that’s what I mean when I say WordPress shouldn’t be everything.

    If I was to use WP as a wiki, and I have, I end up disliking the edit/comment relationship. Regressions are easier with revisions, but prelinking pages and moving them is easier with MediaWiki. Image uploads? Easier on WordPress, as are updates (and don’t get me started on extensions), and html editing in a Wiki can make me drink. At the same time, I have a more flexible template situation, where I can have one that formats a whole page or just bits of one in easy, repeatable ways.

    Both projects have a lot to learn from each other. Both should steal bits from each other. But I think both should be separate because I will always have places were WordPress is a better fit than plain HTML or a wiki or a gallery. Oh, yes, I still use plain HTML in some places. I use Reveal.js for slides. I experiment and find the right tool for the right job.

    Step back again. I got new furniture on my birthday, and it was flatpacked. That means it came with a couple allen wrenches. You know the crappy Ikea L-shaped thing?

    Allen Wrench

    Right. After I put together one chair I announced “Fuck this” to myself and got my ratcheting screwdriver with swappable bits. There was one for this size, I switched to it, and finished three more chairs in the time it had taken me to do one. The tools were similar, but clearly different, and one was better than the other. One was easier, though, in that the chairs came with the less perfect one.

    It seems clear cut, doesn’t it? The one I bought was better than the one they gave me. Duh! That’s how I feel about software. Sometimes what I have isn’t right and I have to go get that other one. But I’m willing to experiment, to try, and to be wrong in order to get to what’s right. And ‘right’ means right for me and how I want to use it, not you, which is why WordPress has a bajillion plugins that do similar things.

    There is not one right way to skin a cat. So why do you think there should be one right CMS?

  • When the Fork Breaks

    When the Fork Breaks

    One morning I awoke to see that one of the lead developers on an open source product was leaving because of ‘creative differences.’ Those are my words. His were a little more angry and frustrated, because it was clear these differences were in the direction of the product. He felt stifled and restrained, saying that the grip the original developer had on the product was at odds with allowing the community to develop it going forward, and he was tired of the fight.

    So he forked it and moved on.

    Cover of Maurice Sendak's

    Regardless of what product this is (and really it doesn’t matter), the decision on my end is whom should I follow?

    On the one hand, this is the lead dev who has applied most (if not all) of the patches I’ve submitted. On the other, the original dev has been working on this for over a decade. Then again, the jump to making this a product I wanted to use happened when the new devs, including the forker, came on board. And the original dev is clearly facing a case of founderitis, where there’s his way or the highway, and not accepting the fact that open source products develop in their own life.

    Taking a deep breath, I do not mean to trivialize the issues here. When angry-making things happen, they happen for more reasons than we can see, and we know that there are always, always, two sides to the issues. At the same time I am not a part of the angry and it’s not my business to delve deep into it, save to come to a place where I can make my educated, thoughtful decision.

    I do have to worry about the stability of both products. How much was this one dev (or these few devs) the cornerstone of the product? Of the features added, whose do I use and like more? Of the ongoing philosophies, which do I more align with? How easy will it be to support the separate version? Do I think this guy is up for it?

    None of this is easy! It’s a jump of who do I trust more, and much of it is a gut feeling. I review the code, I match the changes, and I base my choices on what makes me feel better. But … what about when I’m not a coder? It’s even harder. I have to wait and see which is better, which devs jump with, which users I respect join forks, and even then I know if I wait too long, it’ll be hard to move.

    I moved my photo gallery from a home grown site to Gallery2 to ZenPhoto. I know the pain of hating the changes in a product. I know the pain of forking. But even so, I still can’t tell you how to make that call because even I don’t know.

    All of it depends.

  • Bad Replies to Bad Reviews

    Bad Replies to Bad Reviews

    My plugin brother, Pippin, wrote an awesome post about How to leave a good bad review. In it, he mentions a pretty common kind of email/review:

    Your crappy plugin doesn’t work. Waste of a download..

    Hmm.. I should buy pro!

    Fairly often, people get those as a review in the WordPress.org forums, and ask me (either as a plugin mod or a forum mod) to remove it. Most of the time, I don’t, and tell them that much.

    You see, the issue is not that you got a bad review. We all get them. The issue is how you handle the review. If you get a one-star review slamming your code, and you reply with a reasonable response, then you’ve taken care of the matter in a mature, adult, responsible way. If, instead, you call them names or email them, well then, we’re into the other world.

    If you’re demanding people remove a, single, one star review, in general I think you’re being childish. There are exceptions, where people are bitter and mean and everything falls into a hate-fest with slurs and pejoratives being slung around, and personal attacks galore, then you bet I’ll delete the thread. But you’ll probably get flagged for moderation too.

    Well. That escalated quickly.

    There’s a good way and a bad way to handle a bad review. The bad way comes in two main types: over reactions and under reactions. The unders, thats what you see from people like AT&T or Comcast, who pretty much ignore the complaints and use their power to delete them or shut them down. The overs are people who take their “Oh my god, this customer sucks!” to twitter and everything else, and generally make fools of themselves.

    When you’re asking me to delete a forum post that says “This plugin sucks, the author won’t refund me!” and you’ve made no attempt to handle the situation, I nearly always tell you to try first. “Hey, I’m sorry you’re upset. The no-refund policy was clearly stated on the order page, and I did attempt to work with you to resolve this, but you were asking for a major modification to the code that I didn’t feel comfortable with.” The rest of what I said, though, is gleaned from the paragraph long rant about how a three sentence review was hurting his ratings and no one was downloading his plugin anymore. Clearly because of one, erroneous, one star review.

    Go back to Pippin’s post. At the end, he shares an exchange with a very good ‘negative’ review, and a very good response. For the most part, that’s not what I see developers and the like doing. What I see is that knee-jerk reaction to an angry post, where hate feeds hate and suddenly you’re getting a bunch of bad reviews because you’ve been feeding the anger, and it’s a circle that ends with no one wanting to use your code because you’re mean.

    Recently, a developer who fell into that cycle got ‘busted’ making dupe accounts. Sock puppets, if you will. He used them to try and push his plugins, even though his main accounts were all closed. So we emailed him. We reached out and said “Hey, you know we know this is you. What’s really going on here, man?” And we started talking! He explained his side, we pointed out that the whole thing boiled down to how he’d been mistreating users, and if he could stop that, we were willing to re-enable his account and everything.

    The one thing we did not do was delete his old posts, where he’d kind of lost his mind. Those bad events in the past made him who he was, for better of worse, and whitewashing the past did not change it. There was one way to change it, and that was for him to stop acting like that and to move forward, being a better person.

    For that same reason, I probably won’t delete that bad review. How it changes your product is not in the deletion but in the handling. If you take the task at hand, rise up and approach it fairly and maturely, it says more about you than anything else. If you are reasonable, thoughtful, and fair, you will have a better result in your reviews than anything else I could do with that deleted. You see, I would sooner trust a product that has bad reviews and good responses, than a plugin that has no bad reviews at all. One is understandable, the other is unrealistic.

    And personally? I’d hand over that refund.