Instant Pot Quickstart

I recently got an Instant Pot (IP-DUO60), and it’s been a great addition to the kitchen. I do have to say the manual leaves something to be desired though when it comes to teaching a brand new person how to use it.

First, a couple of obvious, but not-so-obvious tips.

1. You need to add water for it to work right for most pressure-related cooking. It’s a pressure cooker, how obvious, right? Well, when you’re trying to convert some non IP recipes for use in it that have some liquid already, it’s not really clear if you should add more or not. Rule of thumb, unless it already has a lot of free liquid, add a cup or two of water so it can reach pressure. I found this out the hard way when trying to make a Thai Chicken recipe with a lot of salsa as part of the mixture. Chicken was raw until I added a 1-2 cups of water and set it back on program.

2. Pasta without sauce. There are tons of guides about making a one-pot pasta recipe by browning your meat, adding sauce, adding pasta, maybe some water, and go. For great pastas that you just want to eat with maybe some olive oil, this makes it difficult to know what to do. I experimented around and found you can usually make it work well by putting the pasta in the pot with some olive oil mixed around, and then enough water to cover it by a centimeter or so – use your judgement here. Then I set it to cook high pressure for half the time on the pasta package. I got perfectly al-dente tortellini this way.

3. Yogurt. If you already own a yogurt maker, this really doesn’t make the process any easier, except for not having to measure the temperature while its heating. If you don’t have one, it likely will save you some time. Do yourself a favor and cool the milk once you get it to 180F in a cool water bath. I usually just fill up the sink with cold water and let the pot sit in it while stirring the milk mixture around until it cools down. This only takes a couple of minutes (as opposed to letting it sit on its own for 1-2 hours).

More to come.

Mosh – my new SSH replacement

In looking for a better SSH client on Android, I came across JuiceSSH – and while setting it up I noticed there was an option for Mosh that was selectable instead of SSH. After investigating a bit, it turns out that Mosh stands for Mobile Shell, and while it’s optimized for mobile connections, it also works really well for laptop connections.

All of the technical details can be found on the Mosh site, but as point of demonstration, my laptop usage is very mobile. I will go from an office to a mobile hotspot, to home on a VPN, etc; all without losing the Mosh shell. The reason all these network changes work is because it leverages the connectionless UDP instead of TCP, which would break the connection when networks changed.

This means I can always have a shell up at the ready on my terminal, and it’s resilient to changing/poor network conditions. For phone/mobile, it’s just as convenient.

Getting setup with it is fairly easy – just install the Mosh client on your laptop or an app supporting Mosh on your mobile, and then also install the Mosh server on your server. It doesn’t need to run with elevated privileges, meaning you can install it as a regular user (no need for a system wide install / daemon-mode), which is great if that’s your situation.

The initial network setup is done over SSH, and then it hands off to Mosh, so you can still use your public keys for authentication, etc.

Having fun with the cloud on a budget

I’ve always had one or more servers at my disposal as I’ve worked on various projects. Over the last few years I’ve been heavily involved with work projects and haven’t had much time for anything personal. But I’m trying to change that a bit and keep myself sharp on new technologies.

Cloud is everywhere, and it’s one of those terms that everyone says but few people really understand. At it’s core you could say cloud just means “the Internet”, as in “my files are stored in the cloud”. And maybe it originally did. These days now cloud refers more to a kind of highly-scaleable, highly-available virtualized infrastructure that is hosted by someone else. Amazon Web Services is probably the most well known, but there are lots of other players out there.

The general concept is you pay based on usage, like you would your electric bill. It’s really pretty fair. So if you use 10 virtualized servers for 5 hours in a day, and scale back to just one for the rest of the day, you only pay for that usage. However even at the lowest tier on AWS, you end up paying about $10 a month if you wanted to run one server continuously, so creating a real infrastructure for fun can end up being costly (to the hobbyist). Naturally the costs are fine for an actual company who is profiting from it.

So what’s a hobbyist to do? I still have one bare metal server left these days, a rack with a Xeon 5160 and 12GB RAM. I decided to purchase a second Xeon, 8GB more RAM, and will be installing VMWare’s vSphere Hypervisor (ESXi) on it, which is free. It has limits, but nothing I’m going to run up against (>8 vCPUs, more advanced monitoring, etc). I plan to create a few micro instances on it to run basic services, and want to start using infrastructure automation tools to manage the instances. Things like Packer, Consul, and other really interesting things from HashiCorp that I’ve always wanted to play with.

I still plan to have fun with AWS instances for now, experimenting with launching and killing infrastructures, given I’m in the free year/tier on AWS. But most of my persisting fun will be happening on my rack, which won’t cost me anything.

As I go through this transition and process, I plan to document some learnings and examples back here.

Subsonic Under Tomcat & Gentoo

You might be seeing non-working audio output and the following tricky bits in your subsonic log:

Error in jukebox: javax.sound.sampled.LineUnavailableException: Audio Device Unavailable

First thing is to make sure you’re running the Sun JDK and not OpenJDK or something else. Apparently there are things that don’t play well with non-Sun.

If you’ve done this, restarted Tomcat and still have no audio when using Subsonic with Gentoo and Tomcat, remember to add Tomcat to the relevant groups:

groupmems -g pulse -a tomcat

groupmems -g pulse-access -a tomcat

groupmems -g audio -a tomcat

groupmems -g plugdev -a tomcat

To be fair I’m not sure if they’re all necessary, but it works for me. You’ll need to restart Tomcat afterward to make it work.

sudo /etc/init.d/tomcat-6 restart

OpenVZ: VLAN with VEs that Works

So I setup OpenVZ a few months ago in an environment where my Host had two NICs, one on a local “office” network, and another hooked directly up to a WiFi AP that had VLAN’d SSIDs. That part’s not too important, but what is important is the VLANs. It seemed real easy when I did it back then.

However, having to re-do it again for various reasons without the source config, it was not so easy. In fact, I wasted nearly half a day until I figured out you need to add the veth device and the Host adapter to a bridge to even route the traffic properly. The key understanding is that the veth device for OpenVZ has absolutely no relation to any network adapter on the HN. Understand that and you’ll be OK. All it does is create an interface on the HN whose other side is on the VE.

So to save myself some hellish boot configuration, I modified vznetaddbr (below) to create the bridges and bring everything up real nice for me. The key bits are that you defined your veth device with a bridge parameter called ‘vlan###’ where ### is the vlan ID. You’ll also need to change the line near the top that says dev=eth1, unless eth1 is your VLAN’d NIC.

Really, hopefully this helps someone. Should be self-explanatory, but be sure you have brctl and vconfig installed.

# create this file somewhere, and add it to
# /etc/vz/vznet.conf as:
# be sure to chmod +x both
NETIFLIST=$(printf %s "$NETIF" |tr ';' '\n')
ip link set dev "$dev" up
if [ -z "$NETIFLIST" ]; then
   echo >&2 "According to $CONFIGFILE, CT$VEID has no veth interface configured."
   exit 1
for iface in $NETIFLIST; do
    for str in $(printf %s "$iface" |tr ',' '\n'); do
        case "$str" in
                eval "${str%%=*}=\${str#*=}" ;;
#    [ "$host_ifname" = "$3" ] ||
#       continue
    [ -n "$bridge" ] ||
    vlan=`echo "$bridge" | sed s/vlan//`
    echo "Creating $bridge on CT0"
    brctl addbr "$bridge"
    echo "Adding interface $host_ifname to bridge $bridge on CT0 for CT$VEID"
    ip link set dev "$host_ifname" up
    brctl addif "$bridge" "$host_ifname"
    echo 1 >"/proc/sys/net/ipv4/conf/$host_ifname/proxy_arp"
    echo 1 >"/proc/sys/net/ipv4/conf/$host_ifname/forwarding"
    echo "Creating interface $target_if on CT0 for CT$VEID"
    vconfig add "$dev" "$vlan"
    echo "Adding interface $host_ifname to bridge $bridge on CT0 for CT$VEID"
    ip link set dev "$target_if" up
    brctl addif "$bridge" "$target_if"
    echo 1 >"/proc/sys/net/ipv4/conf/$target_if/proxy_arp"
    echo 1 >"/proc/sys/net/ipv4/conf/$target_if/forwarding"
    ip link set dev "$bridge" up
exit 0

Fixing MySQLdb encoding issues with Python

Are you running into encoding issues with MySQLdb on Python? Have you searched high and low only to be told to change your my.cnf settings and create tables with the proper encoding, yet it STILL doesn’t work? In that case, be sure to specify charset='utf8' in your MySQLdb.connect(...) along with the rest of the required parameters. This tiny, neglected setting is what’s actually used to encode unicode back for MySQL. Not configuration files, not table settings, just that.

Of course, you should have a table with a utf8 charset for it to work, but this is the setting that will prevent those latin-1 encoding issues when you swore you didn’t say latin-1 anywhere.

Cloning Hard Drives

Very easy:

dd if=/dev/SOURCE of=/dev/DESTINATION bs=1M

I’ve found in my experience 1M tends to be a solid “bs” number; lower than that and the copy rate is slower, higher than that doesn’t give much performance gain (if any). The SOURCE should be the hard disk that has the image you want to keep and clone, the DESTINATION should be the hard disk that is to be cloned and receive the image on the SOURCE.

This will copy, bit-for-bit, everything on one hard disk to another. Useful for copying over complex workstation/server configurations on machines with the same hardware.

Mounting a JFFS2 filesystem in Linux

This is described on this mailing list, but here’s the short of it in case that page ever dies:

If /dev/mtdblock0 doesn’t exist, do the following

mknod /dev/mtdblock0 b 31 0

Then do the following. The kernel modules can be enabled under Device Drivers->MTD. Make sure to get them all.

modprobe mtd # get this when enabling MTD
modprobe jffs2 # under Filesystems, Misc
modprobe mtdram # under MTD section
modprobe mtdchar # under MTD section
modprobe mtdblock # under MTD section
dd if=your.jffs2 of=/dev/mtd0
mount -t jffs2 /dev/mtdblock0 /your-mount-point